diff --git a/PROJECT_NOTES.md b/PROJECT_NOTES.md index 4ccd111..7d29b38 100644 --- a/PROJECT_NOTES.md +++ b/PROJECT_NOTES.md @@ -167,6 +167,13 @@ - `demo/partials/progress.html` - `demo/partials/steps.html` +Добавлены Chips и Avatar / Identity: + +- `src/scss/components/_chips.scss` +- `src/scss/components/_avatar.scss` +- `demo/partials/chips.html` +- `demo/partials/avatar.html` + Публичный JS API: - `GNexusUIKit.Helper` @@ -184,8 +191,6 @@ Ближайшие полезные additions: -- Chip / Tag: selectable/removable метки для фильтров и labels. -- Avatar / Identity: initials, icon avatar, image avatar, status marker. - Timeline / Activity Log: история событий, audit log, jobs. - Accordion / Disclosure: раскрываемые группы настроек и деталей. - Drawer / Side Panel: контекстные детали и quick edit без полной модалки. diff --git a/README.md b/README.md index e9bb6a3..71d191d 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,8 @@ - Key-Value / Description List - Progress - Steps +- Chips +- Avatar / Identity - Toasts - Cards - Modals @@ -183,6 +185,15 @@ - Staged Progress: сегментированное состояние операции. - Steps: горизонтальный и вертикальный wizard-flow. +### Chips и Avatar + +Секции включают: + +- Chips: static, selectable, removable и state variants. +- Avatar: initials, icon, image, sizes и status marker. +- Identity: avatar + title/meta row. +- Avatar Stack: компактное отображение группы. + ## SCSS Базовые файлы: @@ -225,8 +236,6 @@ Ближайшие полезные компоненты: -- Chip / Tag: selectable/removable метки для фильтров и labels. -- Avatar / Identity: initials, icon avatar, image avatar, status marker. - Timeline / Activity Log: история событий, audit log, jobs. - Accordion / Disclosure: раскрываемые группы настроек и деталей. - Drawer / Side Panel: контекстные детали и quick edit без полной модалки. diff --git a/demo/index.html b/demo/index.html index cdd62b5..27cce58 100644 --- a/demo/index.html +++ b/demo/index.html @@ -98,6 +98,16 @@
  • + + Chips + +
  • +
  • + + Avatar + +
  • +
  • Toasts @@ -132,6 +142,8 @@ @@include("partials/description-list.html") @@include("partials/progress.html") @@include("partials/steps.html") + @@include("partials/chips.html") + @@include("partials/avatar.html") @@include("partials/toasts.html") @@include("partials/cards.html") @@include("partials/modals.html") diff --git a/demo/partials/avatar.html b/demo/partials/avatar.html new file mode 100644 index 0000000..859aa31 --- /dev/null +++ b/demo/partials/avatar.html @@ -0,0 +1,101 @@ +
    +

    Avatar

    +

    + Avatar и Identity показывают пользователя, команду, сервис или объект с initials, icon, image и status marker. +

    + +
    +

    Avatar variants

    + +
    + AV + GN + UI + + + + + + + + + GNexus mark + +
    +
    + +
    +

    Identity row

    + +
    + + AK + + + + Alex Kim + Product Designer + +
    +
    + +
    +

    Avatar stack

    + +
    + AK + JS + MR + +4 +
    +
    + +
    +
    + Avatar HTML + +
    +
    <span class="avatar avatar-secondary is-online">
    +  AK
    +  <span class="avatar-status"></span>
    +</span>
    +
    +<span class="avatar avatar-outline">
    +  <i class="ph ph-user"></i>
    +</span>
    +
    +<span class="avatar">
    +  <img src="/assets/imgs/gnexus-mark.svg" alt="GNexus mark">
    +</span>
    +
    + +
    +
    + Identity HTML + +
    +
    <div class="identity">
    +  <span class="avatar avatar-secondary is-online">
    +    AK
    +    <span class="avatar-status"></span>
    +  </span>
    +  <span class="identity-content">
    +    <span class="identity-title">Alex Kim</span>
    +    <span class="identity-meta">Product Designer</span>
    +  </span>
    +</div>
    +
    + +
    +
    + Avatar Stack HTML + +
    +
    <div class="avatar-stack" aria-label="Assigned users">
    +  <span class="avatar avatar-sm">AK</span>
    +  <span class="avatar avatar-sm avatar-secondary">JS</span>
    +  <span class="avatar avatar-sm avatar-warning">MR</span>
    +  <span class="avatar-stack-count">+4</span>
    +</div>
    +
    +
    diff --git a/demo/partials/chips.html b/demo/partials/chips.html new file mode 100644 index 0000000..b28eb13 --- /dev/null +++ b/demo/partials/chips.html @@ -0,0 +1,99 @@ +
    +

    Chips

    +

    + Chips используются для фильтров, коротких labels, selectable states и removable tokens. +

    + +
    +

    Static chips

    + +
    + Primary + Secondary + Success + Warning + Error + + + Filtered + +
    +
    + +
    +

    Selectable chips

    + +
    + + + + +
    +
    + +
    +

    Removable chips

    + +
    + + Frontend + + + + Design + + + + Review + + +
    +
    + +
    +
    + Static Chips HTML + +
    +
    <div class="chip-group">
    +  <span class="chip chip-primary">Primary</span>
    +  <span class="chip chip-secondary">Secondary</span>
    +  <span class="chip chip-success">Success</span>
    +  <span class="chip">
    +    <i class="ph ph-funnel"></i>
    +    Filtered
    +  </span>
    +</div>
    +
    + +
    +
    + Selectable Chips HTML + +
    +
    <div class="chip-group" aria-label="Filter chips">
    +  <button class="chip chip-selected" type="button" aria-pressed="true">Active</button>
    +  <button class="chip" type="button" aria-pressed="false">Queued</button>
    +  <button class="chip" type="button" aria-pressed="false">Failed</button>
    +</div>
    +
    + +
    +
    + Removable Chips HTML + +
    +
    <span class="chip">
    +  Frontend
    +  <button class="chip-remove" type="button" aria-label="Remove Frontend">
    +    <i class="ph ph-x"></i>
    +  </button>
    +</span>
    +
    +
    diff --git a/src/scss/components/_avatar.scss b/src/scss/components/_avatar.scss new file mode 100644 index 0000000..e3c7d98 --- /dev/null +++ b/src/scss/components/_avatar.scss @@ -0,0 +1,150 @@ +@use "../kit-deps" as *; +@use "typography" as *; + +.avatar { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + width: $control-height-md; + height: $control-height-md; + flex: 0 0 auto; + overflow: hidden; + border: $border-width-base solid $border-color-muted; + color: $color-black; + background: $color-primary; + font-family: $font-family-base; + font-size: $font-size-sm; + font-weight: $font-weight-bold; + line-height: $line-height-base; + text-transform: uppercase; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } + + .ph, + .ph-bold { + font-size: $icon-size-md; + } + + .avatar-status { + position: absolute; + right: -2px; + bottom: -2px; + width: 13px; + height: 13px; + border: $border-width-base solid $surface-page; + background: $color-text-dark; + } + + &.avatar-sm { + width: $control-height-sm; + height: $control-height-sm; + font-size: $font-size-xs; + + .ph, + .ph-bold { + font-size: $icon-size-sm; + } + } + + &.avatar-lg { + width: $control-height-lg; + height: $control-height-lg; + font-size: $font-size-md; + + .ph, + .ph-bold { + font-size: $icon-size-lg; + } + } + + &.avatar-secondary { + background: $color-secondary; + } + + &.avatar-success { + background: $color-success; + } + + &.avatar-warning { + background: $color-warning; + } + + &.avatar-danger, + &.avatar-error { + background: $color-error; + } + + &.avatar-outline { + color: $color-text-light; + background: $surface-panel-muted; + border-color: $color-text-light; + } + + &.is-online .avatar-status { + background: $color-success; + } + + &.is-busy .avatar-status { + background: $color-warning; + } + + &.is-offline .avatar-status { + background: $color-text-dark; + } +} + +.identity { + display: inline-flex; + align-items: center; + gap: $space-3; + min-width: 0; +} + +.identity-content { + display: flex; + flex-direction: column; + gap: $space-1; + min-width: 0; +} + +.identity-title { + color: $color-text-light; + font-size: $font-size-base; + font-weight: $font-weight-semibold; + line-height: $line-height-base; +} + +.identity-meta { + color: $color-text-dark; + font-size: $font-size-sm; + line-height: $line-height-normal; +} + +.avatar-stack { + display: inline-flex; + align-items: center; + + .avatar { + margin-right: -$space-2; + border-color: $surface-page; + } + + .avatar-stack-count { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: $control-height-md; + height: $control-height-md; + padding: 0 $space-2; + border: $border-width-base solid $surface-page; + color: $color-black; + background: $color-warning; + font-size: $font-size-sm; + font-weight: $font-weight-bold; + } +} diff --git a/src/scss/components/_chips.scss b/src/scss/components/_chips.scss new file mode 100644 index 0000000..e13a345 --- /dev/null +++ b/src/scss/components/_chips.scss @@ -0,0 +1,163 @@ +@use "../kit-deps" as *; +@use "typography" as *; + +.chip-group { + display: flex; + flex-wrap: wrap; + gap: $space-2; + align-items: center; +} + +.chip { + display: inline-flex; + align-items: center; + gap: $space-2; + min-height: 30px; + padding: $space-1 $space-3; + border: $border-width-base solid $border-color-muted; + color: $color-text-medium; + background: $surface-panel-muted; + font-family: $font-family-base; + font-size: $font-size-xs; + font-weight: $font-weight-semibold; + line-height: $line-height-base; + text-transform: uppercase; + transition-duration: $motion-base; + transition-timing-function: $motion-ease; + transition-property: color, background, border-color, opacity; + + .ph, + .ph-bold { + font-size: $icon-size-sm; + } + + &::before { + content: ""; + display: inline-block; + width: 7px; + height: 7px; + flex: 0 0 auto; + background: $color-text-dark; + } + + &:has(.ph)::before, + &:has(.ph-bold)::before { + display: none; + } + + .chip-remove { + display: inline-flex; + align-items: center; + justify-content: center; + width: $icon-size-sm; + height: $icon-size-sm; + margin-right: -$space-1; + border: 0; + color: inherit; + background: transparent; + font: inherit; + cursor: pointer; + + &:focus-visible { + @include focus_ring; + } + } + + &.chip-primary { + color: $color-primary; + background: rgba($color-primary, 0.08); + border-color: $color-primary; + + &::before { + background: $color-primary; + } + } + + &.chip-secondary { + color: $color-secondary; + background: rgba($color-secondary, 0.08); + border-color: $color-secondary; + + &::before { + background: $color-secondary; + } + } + + &.chip-success { + color: $color-success; + background: rgba($color-success, 0.08); + border-color: $color-success; + + &::before { + background: $color-success; + } + } + + &.chip-warning { + color: $color-warning; + background: rgba($color-warning, 0.08); + border-color: $color-warning; + + &::before { + background: $color-warning; + } + } + + &.chip-danger, + &.chip-error { + color: $color-error; + background: rgba($color-error, 0.08); + border-color: $color-error; + + &::before { + background: $color-error; + } + } + + &.chip-selected, + &[aria-pressed="true"], + &[aria-selected="true"] { + color: $color-black; + background: $color-primary; + border-color: $color-primary; + + &::before { + background: $color-black; + } + } + + &.chip-selected.chip-secondary, + &.chip-secondary[aria-pressed="true"], + &.chip-secondary[aria-selected="true"] { + background: $color-secondary; + border-color: $color-secondary; + } + + &.chip-disabled, + &:disabled { + color: $color-text-dark; + background: $surface-panel; + border-color: $border-color-muted; + cursor: not-allowed; + opacity: 0.7; + + &::before { + background: $color-grey; + } + } +} + +button.chip, +a.chip { + cursor: pointer; + + &:focus-visible { + @include focus_ring; + } + + @include hover_touch { + color: $color-text-light; + background: $surface-panel-strong; + border-color: $color-secondary; + } +} diff --git a/src/scss/kit.scss b/src/scss/kit.scss index f95ec1b..859d9d7 100644 --- a/src/scss/kit.scss +++ b/src/scss/kit.scss @@ -8,6 +8,8 @@ @use "components/input-group"; @use "components/lists"; @use "components/badges"; +@use "components/chips"; +@use "components/avatar"; @use "components/tables"; @use "components/data-patterns"; @use "components/page-header";