Commit Graph

33 Commits

Author SHA1 Message Date
sdarbinyan
6ca672987e refactor: extract shared app-breadcrumb component (Z14)
Only breadcrumb logic anywhere in the storefront was a local signal +
inline markup inside catalog-container. Extracted a generic
shared/ui/breadcrumb component (rootLabel/items/ariaLabel inputs,
rootClick/itemClick outputs) and repointed catalog-container onto it,
removing the now-dead inline SCSS block. Future breadcrumb usages
(product detail, admin) have something to reuse instead of duplicating.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 21:49:54 +04:00
sdarbinyan
7a2f2a452f refactor: migrate cart payment modals to shared app-dialog primitive
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Third attempt, done properly this time - first two were reverted
(one stopped cleanly on real conflicts, one botched sequencing and
deleted the old focus-trap before finishing the swap).

DialogComponent gains closeOnEscape/closeOnBackdropClick (default true,
backward-compatible with its 13 other call sites) and ariaLabel (for
dialogs with no visible title header). FOCUSABLE_SELECTOR now includes
iframe for the bank-payment panel's focus trap.

Cart wires closeOnBackdropClick=false on both dialogs (in-flight payment
shouldn't cancel on a stray click) and closeOnEscape tied to the bank
popup's open state, so Escape closes the nested bank iframe first and
falls back to the QR view - matches the original priority exactly.

Original geometry (500px QR modal/40px padding, 960x760 bank modal/
56-16-16 padding, both mobile breakpoints) preserved via :host ::ng-deep
overrides scoped per dialog instance - same pattern already used by
product-carousel-widget.component.ts.

cart.component.ts loses ~90 lines of hand-rolled ViewChild/HostListener/
focus-trap code - app-dialog owns all of it now.

Verified live in browser: dialog sizing/padding/aria-label correct at
mobile+desktop, backdrop-click confirmed inert, Escape-priority confirmed
(bank closes first, then QR), initial focus lands on close button.
83/83 tests pass, tsc/build clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 11:13:33 +04:00
sdarbinyan
6d075fc5b9 perf: drop @lucide/angular, hand-roll used icons - initial bundle 13.68MB -> 2.64MB
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
@lucide/angular shipped its entire ~1500-icon set in the initial bundle
despite the app only using 85 named-imported icons - confirmed upstream
tree-shaking failure (sideEffects:false, clean named imports, single
non-splittable fesm file). Replaced icon-registry.ts/icon.component.ts
with hand-rolled inline SVG rendering of just the 85 used icons,
transcribed from lucide's own node data for pixel-identical output.
Zero call-site changes - AppIconName and app-icon's public API unchanged.

Also: karma-coverage wired (npm run test:coverage), baseline captured
in docs/SPRINT-PLAN-NEXT.md (32% statements / 18.5% branches).

Cart-modal -> app-dialog migration was attempted and reverted - real
conflicts (backdrop-close, nested-modal escape priority, iframe sizing),
documented in docs/FUTURE_FEATURES.md for a properly scoped follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 10:55:00 +04:00
sdarbinyan
48bcffa22c feat: close stub-page gaps - profile login/logout, admin Reports/Settings, Help/Docs links
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Sprint A: storefront header profile control (login/logout only, no menu),
wired to existing customer Telegram auth (AuthService).

Sprint B: backoffice/reports page, reuses AdminAnalyticsFacade (Sales,
Top Products, Marketplace Health cards + CSV export).

Sprint C: backoffice/settings page, admin UI density preference
(comfortable/compact), localStorage-persisted, applied to app-table
across all admin list pages.

Sprint D: admin bottom-nav Help -> mailto using existing supportEmail,
Documentation -> external link via new TenantConfig.documentationUrl.
AdminNavLink gains externalHref for non-routerLink nav entries.

Docs: docs/GLOBAL-SPRINT-PLAN.md tracks the full sprint breakdown.
docs/COMING-SOON-AUDIT.md removed, folded into docs/KNOWN-ISSUES.md.
docs/BACKEND.md updated with the new documentationUrl bootstrap field.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 17:48:50 +04:00
sdarbinyan
65c6d6f5d1 feat: Page Editor UX Phase 2 - unsaved changes panel, property search, reset property, empty states
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
- ProjectEditorFacade.resetField(key): field-level revert-to-original, reusing getByPath + a new immutable setByPath (write-side counterpart, scalar/object dot-paths only).
- app-form-field gains showReset/resetLabel/(resetClicked) - a reusable per-field reset affordance, wired on branding logo/title and theme primary/background color.
- Save bar: unsaved-changes count is now clickable, expanding a field-level diff list (reuses facade.changeSummary(), already built for the Preview tab) with jump-to-section links.
- BuilderPropertySearchComponent: filters EditorSchemaService.all() by translated label/hint, jumps to the owning section - no new registry, reuses the existing schema.
- navigation-section: app-empty-state (existing component) added for empty header/footer link lists.
- Reset Section and Draft/Published badge were already implemented; not touched.
- New copy added as translation keys (en/ru/hy).
2026-07-27 11:12:35 +04:00
sdarbinyan
42f11dd8c0 feat: Page Editor UX Phase 1 - live preview, hover mapping, visual layout picker
- PreviewHighlightService + appHighlightSource directive: shared hover/focus bridge between editor fields and the schematic live preview.
- BuilderLivePreviewComponent: in-page schematic homepage render (header/hero/blocks/footer) reading the same bootstrap the sections mutate, highlighting the area matching the active field.
- VisualLayoutPickerComponent: card-based layout picker (ControlValueAccessor, same shape as app-select) replacing the raw layout <select> in homepage-section.
- app-form-field gains optional usedBy/usedByLabel inputs for the "Where is this used?" helper text, wired into aria-describedby.
- Wired homepage/branding/theme sections with highlight sources + usedBy hints; live preview panel shown in project-editor-page for those three sections.
- All new copy added as translation keys (en/ru/hy).
2026-07-27 10:00:42 +04:00
sdarbinyan
6c6fa00ccf fix(ui): replace native confirm()/alert() with shared dialogs and toasts
New app-confirm-dialog (wraps existing app-dialog + app-button) replaces
every native confirm() across media library bulk-delete, static pages
editor (delete/bulk-delete), builder save-bar (publish/reset-draft),
project-editor-page (reset-section), homepage/languages/widgets sections
(remove block/language/widget), and cart (clear-cart).

Cart's native alert() calls (delivery/terms validation, email send
success/failure) now route through the existing UserNotificationService
toast pipeline instead.

No native confirm()/alert()/prompt() remain in production UI.
2026-07-26 00:08:00 +04:00
sdarbinyan
1163bfd88a fix(storefront): replace hardcoded strings with i18n, neutral empty-state wording
- Route aria-label/alt/title strings (rating, discount, carousel arrows,
  hero slides, dialog close, toast dismiss, QR code, bank payment iframe,
  guest checkout fallback) through the translate pipe/service instead of
  literal English.
- Drop the "Oops!"/"Упс!" apology framing from category/subcategory empty
  states (en/ru/hy) - zero results is not an error.
2026-07-25 23:54:08 +04:00
sdarbinyan
6d663eb238 fix(icons): replace broken Material-icon-ligature text with app-icon in search suggestions
Search suggestions/popular-searches (search-autocomplete.service.ts,
search.facade.ts) set icon values like 'inventory_2', 'category', 'sell',
'auto_awesome', 'trending_up' - Material Symbols ligature names rendered as
raw {{ item.icon }} text in search-bar.component.html. No Material Icons
font is loaded anywhere in this Lucide/app-icon-based app, so these
rendered as literal garbled text ("inventory_2", etc.) instead of icons.

- SearchSuggestion.icon retyped from string to AppIconName (search.model.ts)
- Suggestion icon values mapped to registered app-icon names: product->package,
  category->folder, brand->tag, ai->zap, popular/trending->trendingUp (new
  registry entry, LucideTrendingUp)
- search-bar.component now renders <app-icon [name]="item.icon" /> instead of
  the raw ligature string, and its icon-only clear ("x") button now renders
  app-icon name="x" instead of a bare literal "x" character glyph

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 20:15:47 +04:00
sdarbinyan
fb1afb72d4 fix(storefront): WCAG 2.1 AA accessibility fixes
RC A11Y-01 audit pass, storefront + shared app-shell chrome only. Builds
on RC-Visual-02/RC-Premium-01/RC STORE-01 without redoing that work.

- Skip link: added first-focusable "skip to main content" link (app.html,
  styles.scss .skip-link/.sr-only), targeting new #main-content landmark.
  New app.skipToContent i18n key in en/ru/hy.
- Header: mobile menu items stayed keyboard-focusable and screen-reader
  reachable while visually collapsed (max-height:0 with no visibility
  toggle) - fixed with visibility:hidden + matched transition-delay.
  Desktop search input (readonly, click-to-navigate) had no keyboard
  activation - added aria-label + (keydown.enter).
- Cart payment/bank-payment modals: custom (non-app-dialog) UI had no
  focus trap, no Escape handling, and never returned focus to the
  triggering element - ported app-dialog's confirmed-correct
  focus-trap/Escape/return-focus pattern directly onto cart.component.ts.
  Added role="dialog"/aria-modal/aria-label to both panels and
  role="status"|"alert"/aria-live to every payment-status screen so
  screen readers announce state changes (creating/waiting/success/
  error/timeout).
- Search combobox: suggestion listbox had no role="combobox" wiring on
  the input and suggestion buttons weren't role="option" - added
  aria-autocomplete, aria-controls, aria-activedescendant, aria-selected
  so the existing arrow-key navigation is announced to screen readers.
- Product tabs: tablist/tab pattern was incomplete (no role="tablist",
  no tabpanel) - added role="tablist" + ids to product-tabs.component,
  role="tabpanel"/aria-labelledby to the content panel in
  product-details-container.
- Review form: rating/text validation errors weren't associated with
  their controls (no aria-describedby, no role="alert") - fixed; added
  aria-required to the review textarea.
- delivery-selector: added aria-required to the delivery <select> when
  a selection is mandatory.
- Shared app-icon component: doc comment claimed "decorative by default
  (aria-hidden)" but no aria-hidden was ever applied - fixed to actually
  set aria-hidden="true" when undecorated, and role="img"/aria-label
  when ariaLabel is passed. Shared component, affects every icon-only
  usage app-wide, no visual change.
- Color contrast: --text-light fails WCAG AA 4.5:1 for normal text in
  every theme (dexar 3.39:1, lavero/novo 2.54:1 against white). The two
  in-scope usages (company-details org-short/basis, review-form
  upload-placeholder) switched to --text-secondary (4.55:1-7.56:1,
  passes), same visual family, no layout change.

Flagged, not fixed (design-system decisions, not polish):
- --border-color fails WCAG 1.4.11 3:1 for UI-component boundaries in
  every theme (dexar 1.42:1, lavero/novo 1.24:1 vs white) - pervasive
  token used by hundreds of borders app-wide; needs theme-owner sign-off.
- --success-color/--warning-color/--error-color/--info-color used as
  plain text-on-white in several places (product-information,
  question-card, review-form, compare-page) fail 4.5:1 (2.15-3.76:1) -
  genuine brand semantic colors, changing them to pass would visibly
  shift the palette; needs a deliberate token decision.
- Header mobile-menu max-height/padding transition (pre-existing,
  unrelated to this fix) flagged by design lint as layout-thrashing;
  left as-is per the "no layout/business-logic changes" constraint.

Verified: npx tsc --noEmit clean; npm run build green (only the
pre-existing bundle-budget warning, unrelated to this pass).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 08:46:18 +04:00
sdarbinyan
5c54541b4c style(design-system): normalize font-weight literals (400/500/600/700) to tokens
Mechanical, value-preserving: font-weight: 400/500/600/700 -> var(--font-weight-normal/medium/semibold/bold, <same value>) across src/app.
Note: cart.component.scss now sits ~771 bytes over its per-file budget
in angular.json due to longer var() strings; non-fatal build warning,
noted in docs/UI-DESIGN-REVIEW.md as a follow-up (either bump the
component style budget slightly or accept the warning).
2026-07-20 03:28:56 +04:00
sdarbinyan
aaa3604cd4 style(design-system): apply typography/spacing/radius tokens to shared/ui component library
Normalized the 18 shared/ui components (button, input, select, badge,
card, section-card, table, dialog, empty-state, form-field, pagination,
toggle, image-field, key-value-editor, locale-tabs, color-picker,
code-editor, skeleton) — these are the reusable primitives consumed
across storefront/builder/backoffice — to use the new
--font-size-*/--font-weight-*/--line-height-* tokens and the
--radius-xs/--radius-full tokens introduced in the previous commit,
replacing one-off literal values (0.875rem, 13px, 999px, 12px, etc.).

Fixes found along the way:
- code-editor.component.scss: focus border/shadow used a hardcoded
  #497671 (the dexar tenant's primary color) instead of
  var(--primary-color) — would not adapt to the lavero/novo tenant
  themes. Now theme-aware.
- section-card.component.scss used raw 16px/18px/14px radius/padding
  instead of the --radius-lg/--space-* tokens the sibling card
  component already used, so cards and section-cards had slightly
  different rounding/padding for no reason. Aligned to the same scale.
- toggle/badge/item-tag: raw 999px pill radius replaced with the new
  --radius-full token.

Deferred: syntax-highlighting colors in code-editor (.cm-*) are
intentional and left untouched; tenant brand colors in the three
theme.scss files are intentional per-tenant palettes, left untouched.
2026-07-20 03:23:22 +04:00
sdarbinyan
f563d47e8a fix(icons): standardize dropdown/select/pagination/expander chevrons
app-select (the shared select used across every admin form) rendered
the browser's native dropdown indicator - inconsistent across
Chrome/Firefox/Safari and outside the icon system entirely. Hid it
(appearance: none) and added a consistent chevronDown via app-icon.

app-pagination used literal HTML entities (&laquo; / &raquo;) for
prev/next instead of icons. Replaced with chevronLeft/chevronRight.

Every native <details>/<summary> expander (7 call sites across admin
product form, page editor, and the builder's widget advanced-settings
panel) relied on the browser's default disclosure triangle, which
again varies per browser and shares no visual relationship with the
rest of the icon system. Added one global CSS rule (details > summary)
that hides the native marker and draws the same Lucide chevron path
used everywhere else, animated on open/close - covers all 7 without
touching each template.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 02:59:22 +04:00
sdarbinyan
e1112bbd50 fix(icons): replace remaining hand-rolled inline SVGs with Lucide
telegram-login: close X and lock icons (auth-gate icon reused across
telegram-login and cart - same 'log in required' concept, now the
same lock icon in both instead of two different hand-drawn shapes);
retry/refresh icon (QR expired/error states, was duplicated). Added
missing aria-label on the close button (had none).

catalog-empty-state, category, subcategories, item-detail: empty-state
illustrations (package/search/grid), add-to-cart icons, success/error
status icons, and thumbs up/down vote icons replaced. Rating stars
(item-detail, both product rating and per-review rating) now use one
Star icon with a color input and a .dx-star--filled CSS class for the
solid/outline toggle, instead of hand-toggling raw fill/stroke SVG
attributes - fixes the same rating-star pattern being drawn two
different ways (outline-only in the carousel earlier, fill-toggling
here).

Added color input to app-icon (was stroke-only via currentColor
before) and four more icons to the registry: refresh, thumbsUp/Down,
locate/mapPin (added earlier this session).

Also fixed the currency-dropdown chevron in language-selector that a
prior replace_all missed (same markup, different [class.rotated]
binding target).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 02:53:52 +04:00
sdarbinyan
3837ddfb2d fix(icons): replace hand-rolled inline SVGs with Lucide (cart, selectors, carousel)
Cart: trash/X/plus/minus/lock icons replaced with app-icon. Removed
the standalone EmptyCartIconComponent entirely - it was a duplicate
80px shopping-cart glyph with no unique illustration, only ever used
in one place; now app-icon name="cart" inline.

Language/region selectors: dropdown chevrons (duplicated 3x with
identical path data across two components) unified on
chevronDown; region pin, locate (crosshair), and globe icons replaced.
New mapPin/locate icons added to the registry.

Items carousel: rating star and add-to-cart icons replaced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 02:45:37 +04:00
sdarbinyan
043192accf fix(icons): migrate Marketplace Builder to Lucide
Replace every PrimeIcons pi-* usage across the builder: overview page
(back link, next-step arrow, section cards, readiness checklist,
quick links), sidebar nav (group/section status dots), main layout
(back/home/menu/help icons), brand + homepage overview panels
(checklist ok/pending dots, contrast warning), footer/homepage/widgets
section editors (drag handles, move up/down, duplicate, remove), and
the HTML editor toolbar (list/link/image/table/divider/code/embed).

Notable correctness fix: PrimeIcons reused pi-bars for both the
hamburger menu toggle AND every drag handle - two different meanings
sharing one icon (exactly the kind of icon collision the audit calls
out). Added a dedicated 'grip' icon (GripVertical) for drag handles so
menu and drag-to-reorder are visually distinct.

Added a global .spin utility (icon-registry has no built-in spinner
animation) for the one loading-spinner icon in the builder overview
checklist.

All icon-bearing fields (BuilderGroup.icon, BlockCatalogEntry.icon,
WIDGET_ICONS, STATUS_ICON, HtmlEditorToolbarCommand.icon, etc.) are
now typed AppIconName instead of string.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 02:31:06 +04:00
sdarbinyan
9569b6dc46 fix(icons): migrate admin dashboard to Lucide
Replace every PrimeIcons pi-* class (static and data-driven) in the
admin dashboard area with app-icon: dashboard-card, dashboard-shortcut-
card, dashboard-status-row, dashboard-timeline, and the icon data in
admin-dashboard.facade.ts / admin-dashboard-page.component.ts. Icon
fields on AdminDashboardQuickAction/Shortcut/DashboardTimelineEntry
are now typed AppIconName instead of string, so a typo or unmapped
icon name is a compile error instead of a silently blank icon.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 02:13:41 +04:00
sdarbinyan
f3c8a8cc96 feat(icons): add Lucide icon foundation
Add @lucide/angular dependency and a single shared entry point for
every icon in the app: app-icon (src/app/shared/ui/icon), backed by a
canonical name -> Lucide-icon registry (icon-registry.ts) covering
every concept the RC icon audit needs across storefront, builder, and
backoffice. One name per meaning, one default size/stroke-width, so
every screen renders the same icon the same way.

Package note: lucide-angular (unscoped) is deprecated upstream in
favor of @lucide/angular - installed the maintained package directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 01:49:38 +04:00
sdarbinyan
c452d28eca fix(admin): P0 user-reported bugs - raw keys, table overflow, builder escape route
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

- Transactions: 'adminTransactions.flag'/'clearFlag' raw keys rendered on the fraud toggle button (missed by earlier audit because the key sits inside a ternary); added en/ru/hy strings with merchant wording ('Flag as suspicious')
- Table overflow on Customers/Transactions root-caused: app-table host is a grid item with default min-width:auto, so wide tables stretched their parent card instead of scrolling inside the wrapper; shared TableComponent now declares display:block/min-width:0/max-width:100% on its element selector (encapsulation None - :host would not match), fixing every admin table at once; verified in browser: cards contained, wrapper scrolls internally
- Builder trap root-caused: section editor pages (/:lang/edit/<section>) had zero routes to the backoffice - only a link back to the builder overview - so admins inside a section could not return to the dashboard; sidebar now has a persistent 'Back to dashboard' link (new builder.backToDashboard key, en/ru/hy); verified navigation lands on /ru/backoffice/dashboard
2026-07-19 08:25:29 +04:00
sdarbinyan
2a8c1166b1 feat(project-editor): syntax-highlighted code editor for HTML raw mode
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
- shared app-code-editor: overlay textarea + highlighted <pre> layer,
  no external dependency (Monaco/CodeMirror)
- tokenizeCss: selector/property/value/string/comment/at-rule aware,
  brace-depth state machine
- tokenizeHtml: tags + comments colored, delegates <style> block content
  to tokenizeCss (that's where static-page CSS is actually authored)
- marketplace-html-editor raw-code mode now uses app-code-editor instead
  of a plain textarea

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 16:28:53 +04:00
sdarbinyan
b183410888 feat(project-editor): reusable image-field (thumbnail+replace+remove), branding OG image+gallery
- shared app-image-field component: thumbnail preview, replace, remove, opens media-picker
- branding: add socialImageUrl + galleryUrls fields, wire to new image-field
- footer: logo + payment icon fields use image-field (drop manual media-picker plumbing)
- i18n: common.remove, adminCategories.replaceImage, builder.socialImage/gallery keys (en/ru/hy)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 15:22:45 +04:00
sdarbinyan
e18f542357 feat(shared-ui): add toggle, select, color-picker, section-card, locale-tabs, key-value-editor primitives
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 01:59:45 +04:00
sdarbinyan
dbd905b02f fix(design-system): wire label/hint/error accessibility from FormField to Input
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
FormFieldComponent's label had [for]=fieldId but nothing ever gave the
projected control a matching id, and aria-describedby was set on a wrapper
div instead of the actual input - so screen readers announced neither the
label association nor the hint/error text.

Added FormFieldContext, an injectable abstract class FormFieldComponent
provides via its own providers array (visible to content-projected children,
same mechanism Angular Material's mat-form-field/matInput relationship
relies on). InputComponent optionally injects it and self-applies id and
aria-describedby when nested inside app-form-field.

This retroactively fixes every form built across Sprint 3-5 (Static Pages
editor, Media Manager, Products List/Form, Project Editor sections) with
no template changes needed anywhere else.

Verified in browser: input id matches label's for attribute, and
aria-describedby correctly points to the rendered hint/error text.

Completes Sprint 5 (UI/UX Polish): Admin Products List, Admin Product Form,
Project Editor sections (9 of 11), and this accessibility fix.
2026-07-15 08:01:54 +04:00
sdarbinyan
bc03cc3d27 feat(design-system): add reusable Pagination primitive
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Standalone, OnPush. Computes truncated page range with ellipsis, composes
existing app-button (ghost/sm) for prev/next controls rather than duplicating
button styling. aria-current on active page, nav aria-label. Colors/radius/
spacing via existing tenant CSS vars with fallbacks.

Completes Sprint 6 Design System primitives: Button, Input, Card, Badge,
Dialog, FormField, EmptyState, Skeleton, Table, Pagination.
2026-07-15 03:45:40 +04:00
sdarbinyan
bc46a755b1 feat(design-system): add reusable Table shell primitive
Standalone, OnPush, ViewEncapsulation.None scoped under .app-table/.app-table-wrapper
so projected thead/tbody markup receives consistent styling. Scroll container for
responsive overflow. Colors/radius/spacing via existing tenant CSS vars with fallbacks.
2026-07-15 03:44:01 +04:00
sdarbinyan
a51aa3cf7e feat(design-system): add reusable Skeleton loading primitive
Standalone, OnPush, aria-hidden. Shapes text/circle/rect, configurable
width/height. Shimmer respects prefers-reduced-motion. Colors via
existing tenant CSS vars with fallbacks.
2026-07-15 03:42:18 +04:00
sdarbinyan
efdb03f23e feat(design-system): add reusable EmptyState primitive
Standalone, OnPush. title required input (caller supplies translated text),
optional description, icon/actions content-projection slots. Colors via
existing tenant CSS vars with fallbacks.
2026-07-15 03:40:56 +04:00
sdarbinyan
439d3d3c95 feat(design-system): add reusable FormField wrapper primitive
Standalone, OnPush. Label/hint/error slots, required marker, aria-describedby
wiring, role=alert on error. Colors via existing tenant CSS vars with fallbacks.
2026-07-15 03:39:19 +04:00
sdarbinyan
27ff3169b9 feat(design-system): add reusable Dialog primitive
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Standalone, OnPush. Backdrop click and Escape close, focus trap with
return-focus on close, role=dialog/aria-modal. Sizes sm/md/lg. Colors/
radius/shadow/spacing via existing tenant CSS vars with fallbacks.
2026-07-15 03:34:52 +04:00
sdarbinyan
5cbc9e4873 feat(design-system): add reusable Badge primitive
Standalone, OnPush. Variants neutral/primary/success/warning/danger/info.
Colors consumed via existing tenant CSS vars with fallbacks.
2026-07-15 03:33:09 +04:00
sdarbinyan
b309afbe8e feat(design-system): add reusable Card primitive
Standalone, OnPush, content-projection container. Padding none/sm/md/lg,
bordered and interactive variants. Colors/radius/shadow/spacing consumed
via existing tenant CSS vars with fallbacks.
2026-07-15 03:31:31 +04:00
sdarbinyan
2fc9051f86 feat(design-system): add reusable Input primitive
ControlValueAccessor-based, standalone, OnPush. Sizes sm/md/lg, states default/error/success.
Colors/radius/spacing/transitions consumed via existing tenant CSS vars (--border-color,
--primary-color, --error-color, --success-color, etc) with fallbacks - compatible with
bootstrap JSON theming and Project Editor live preview.
2026-07-15 03:30:05 +04:00
sdarbinyan
4e63ff97bb feat(design-system): add reusable Button primitive
Sprint 6 (pulled forward as prerequisite to Sprint 3). First Design
System component: app-button, standalone/OnPush, variants
(primary/secondary/ghost/danger), sizes (sm/md/lg), loading + disabled
states, focus-visible ring, reduced-motion-aware spinner. Colors/radius/
shadow/spacing consumed via existing tenant-driven CSS vars
(--primary-color, --bg-primary, --radius-md, --shadow-sm, --space-*) —
no new hardcoded palette, fully compatible with bootstrap JSON theming
and Project Editor live preview.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 03:22:40 +04:00