Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add avatar component #115

Merged
merged 3 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions components/Avatar/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@ikun-ui/avatar",
"version": "0.0.9-beta.2",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"svelte": "dist/index.js",
"types": "src/index.ts",
"keywords": [
"svelte",
"svelte3",
"web component",
"component",
"react",
"vue",
"svelte-kit",
"dx"
],
"scripts": {
"build": "npm run build:js && npm run build:svelte",
"build:js": "tsc -p . --outDir dist/ --rootDir src/",
"build:svelte": "svelte-strip strip src/ dist",
"publish:npm": "pnpm publish --no-git-checks --access public"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@ikun-ui/icon": "workspace:*",
"@ikun-ui/utils": "workspace:*",
"baiwusanyu-utils": "^1.0.14"
},
"devDependencies": {
"@tsconfig/svelte": "^5.0.0",
"svelte-strip": "^2.0.0",
"tslib": "^2.6.1",
"typescript": "^5.1.6"
}
}
54 changes: 54 additions & 0 deletions components/Avatar/src/index.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { KIcon } from '@ikun-ui/icon';
import { createCls, getPrefixCls } from '@ikun-ui/utils';
import { isNumber } from 'baiwusanyu-utils';

export let icon: string = '';
export let src: string = '';
export let srcSet: string = '';
export let alt: string = '';
export let fit: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' = 'cover';
export let size: string | number = '50px';
export let radius: string | number = '4px';
export let cls: string = '';

let avatarSize: string = size;
$: if (isNumber(size)) {
avatarSize = `${size}px`;
}

let avatarRadius: string = radius;
$: if (isNumber(radius)) {
avatarRadius = `${radius}px`;
}

let hasLoadError: boolean = false;
$: if (src) {
hasLoadError = false;
}

const dispatch = createEventDispatcher();

const onError = (event: CustomEvent) => {
hasLoadError = true;
dispatch('error', event);
};

// remove extra space from class names
const avatarCls = getPrefixCls('avatar');
$: cnames = createCls(avatarCls, cls);
</script>

<div
class={cnames}
style="width: {avatarSize}; height: {avatarSize}; border-radius: {avatarRadius}"
>
{#if (src || srcSet) && !hasLoadError}
<img {src} {alt} {srcSet} on:error={onError} style="object-fit: {fit}" />
{:else if icon}
<KIcon v-else-if="icon" {icon}></KIcon>
{:else}
<slot v-else />
{/if}
</div>
6 changes: 6 additions & 0 deletions components/Avatar/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="./types" />
import Avatar from './index.svelte';

export default Avatar;

export { Avatar as KAvatar };
1 change: 1 addition & 0 deletions components/Avatar/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="svelte" />
11 changes: 11 additions & 0 deletions components/Avatar/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",

"compilerOptions": {
"noImplicitAny": true,
"strict": true,
"declaration": true
},
"include": ["src/**/*.ts", "src/**/*.svelte"],
"exclude": ["node_modules/*", "**/*.spec.ts"]
}
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ const components = [
text: 'Data',
collapsed: false,
items: [
{
text: 'Avatar',
link: '/components/KAvatar'
},
{
text: 'Badge',
link: '/components/KBadge'
Expand Down
75 changes: 75 additions & 0 deletions docs/components/KAvatar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: KAvatar
lang: en-US
---

# KAvatar

Avatars can be used to represent people or objects. It supports images, Icons, or characters.

## Install

::: code-group

```bash [pnpm]
pnpm add @ikun-ui/avatar
```

```bash [yarn]
yarn add @ikun-ui/avatar
```

```bash [npm]
npm install @ikun-ui/avatar
```

:::

## Basic usage

Use `size` and `radius` prop to set avatar's size and radius.

<demo src="../../../../example/avatar/basic.svelte" github='Avatar'></demo>

## Types

It supports images, Icons, or characters.

<demo src="../../../../example/avatar/types.svelte" github='Avatar'></demo>

## Fallback

fallback when image load error.

<demo src="../../../../example/avatar/fallback.svelte" github='Avatar'></demo>

## Fit Container
baiwusanyu-c marked this conversation as resolved.
Show resolved Hide resolved

Set how the image fit its container for an image avatar, same as [object-fit <span class="i-carbon-link text-12px" />](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit).

<demo src="../../../../example/avatar/fit-container.svelte" github='Avatar'></demo>

## Avatar Props

| Name | Type | Default | Description |
| ------ | ---------------------------------------------------- | ------- | ---------------------------------------------------------- |
| icon | `string` | `''` | The class name of the icon, following the unocss standard. |
| src | `string` | `''` | the source of the image for an image avatar.. |
| srcSet | `string` | `''` | native attribute `srcset` of image avatar. |
| alt | `string` | `''` | native attribute `alt` of image avatar. |
| fit | `fill` / `contain` / `cover` / `none` / `scale-down` | `cover` | set how the image fit its container for an image avatar. |
| size | `string` / `number` | `50px` | avatar size, the default unit is `px`. |
| radius | `string` / `number` | `4px` | avatar radius, the default unit is `px`. |
| cls | `string` | `''` | Additional class for |
vtrbo marked this conversation as resolved.
Show resolved Hide resolved

## Avatar Events

| Name | Description | Type |
| ----- | ------------------------------ | ----------------------------- |
| error | trigger when image load error. | `(event: CustomEvent)=> void` |

## Avatar Slots

| Name | Description |
| ------- | ------------------------- |
| default | Customize default content |
12 changes: 12 additions & 0 deletions docs/example/avatar/basic.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import { KAvatar } from '@ikun-ui/avatar';

const src = 'https://ikun-ui.netlify.app/logo.svg';
</script>

<div class="flex items-center justify-around">
<KAvatar {src}></KAvatar>
<KAvatar {src} radius={0}></KAvatar>
<KAvatar {src} size={60} radius={10}></KAvatar>
<KAvatar {src} size="5rem" radius="50%"></KAvatar>
</div>
7 changes: 7 additions & 0 deletions docs/example/avatar/fallback.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import { KAvatar } from '@ikun-ui/avatar';
</script>

<KAvatar icon="i-carbon-image">
<img src="https://ikun-ui.netlify.app/error.svg" />
</KAvatar>
15 changes: 15 additions & 0 deletions docs/example/avatar/fit-container.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script>
import { KAvatar } from '@ikun-ui/avatar';

const src = 'https://www.svelte.cn/svelte-logo-horizontal.svg';
const fits = ['fill', 'contain', 'cover', 'none', 'scale-down'];
</script>

<div class="flex items-center justify-between">
{#each fits as fit}
<div>
<div class="text-center mb-6px text-12px color-#909399">{fit}</div>
<KAvatar {src} {fit} size={100} />
</div>
{/each}
</div>
9 changes: 9 additions & 0 deletions docs/example/avatar/types.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script>
import { KAvatar } from '@ikun-ui/avatar';
</script>

<div class="flex items-center justify-around">
<KAvatar src="https://ikun-ui.netlify.app/logo.svg"></KAvatar>
<KAvatar icon="i-carbon-settings"></KAvatar>
<KAvatar>User</KAvatar>
</div>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"dependencies": {
"baiwusanyu-utils": "^1.0.14",
"@ikun-ui/utils": "workspace:*",
"@ikun-ui/avatar": "workspace:*",
"@ikun-ui/badge": "workspace:*",
"@ikun-ui/button": "workspace:*",
"@ikun-ui/button-group": "workspace:*",
Expand Down
9 changes: 9 additions & 0 deletions play/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { KAvatar } from '@ikun-ui/avatar';
import { KBadge } from '@ikun-ui/badge';
import { KButton } from '@ikun-ui/button';
import { KButtonGroup } from '@ikun-ui/button-group';
Expand Down Expand Up @@ -103,6 +104,14 @@
KModal
</KButton>

<div class="my-10px">
<KAvatar>User</KAvatar>
<KAvatar icon="i-carbon-settings" size={30} radius="50%"></KAvatar>
<KAvatar src="https://ikun-ui.netlify.app/logo.svg"></KAvatar>
<KAvatar src="https://ikun-ui.netlify.app/logo.svg" size="60px" radius={8}></KAvatar>
<KAvatar src="https://ikun-ui.netlify.app/logo.svg" size={100} radius="50%"></KAvatar>
</div>

<div class="my-10px">
<div class="mb-10px">KBadge</div>
<KBadge cls="mr-40px" value={badgeNumber}>
Expand Down
28 changes: 28 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions preset/src/shortcuts/avatar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const avatarShortcuts: Record<string, string> = {
// avatar
'k-avatar':
'infcc v-mid box-border text-ikun-white text-14px text-center bg-#c0c4cc overflow-hidden [&>img]:(block b-none max-w-full w-full h-full)',

// dark
'k-avatar__dark': 'dark:bg-#6C6E72'
};
6 changes: 6 additions & 0 deletions preset/src/shortcuts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { UserShortcuts } from 'unocss';
import { baseShortcuts } from './base';
import { commonShortcuts } from './common';
import { iconShortcuts } from './icon';
import { avatarShortcuts } from './avatar';
import { badgeShortcuts } from './badge';
import { buttonShortcuts } from './button';
import { buttonGroupShortcuts } from './button-group';
Expand All @@ -26,6 +27,8 @@ export default [
commonShortcuts,
// icon
iconShortcuts,
// avatar
avatarShortcuts,
// badge
badgeShortcuts,
// button
Expand Down Expand Up @@ -64,6 +67,7 @@ export default [

export function getSafeList() {
const iconList = Object.keys(iconShortcuts);
const avatarList = Object.keys(avatarShortcuts);
const badgeList = Object.keys(badgeShortcuts);
const buttonList = Object.keys(buttonShortcuts);
const buttonGroupList = Object.keys(buttonGroupShortcuts);
Expand Down Expand Up @@ -94,6 +98,7 @@ export function getSafeList() {
.concat(inputList)
.concat(maskList)
.concat(eyeDropperList)
.concat(avatarList)
.concat(badgeList)
.concat(buttonList)
.concat(buttonGroupList)
Expand All @@ -104,6 +109,7 @@ export function getSafeList() {
export { baseShortcuts } from './base';
export { commonShortcuts } from './common';
export { iconShortcuts } from './icon';
export { avatarShortcuts } from './avatar';
export { badgeShortcuts } from './badge';
export { buttonShortcuts } from './button';
export { buttonGroupShortcuts } from './button-group';
Expand Down