@mhmo91/schmancy 0.9.23 → 0.9.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/custom-elements.json +52 -15
  2. package/dist/agent/schmancy.agent.js +318 -72
  3. package/dist/agent/schmancy.agent.js.map +1 -1
  4. package/dist/agent/schmancy.manifest.json +172 -3
  5. package/dist/area-CFLFXu0Z.cjs.map +1 -1
  6. package/dist/area-CfozaCAZ.js.map +1 -1
  7. package/dist/card-CTUaARLm.js.map +1 -1
  8. package/dist/card-DtN6p1Jq.cjs.map +1 -1
  9. package/dist/chips-B-27tj7O.cjs.map +1 -1
  10. package/dist/chips-DhAWrSgi.js.map +1 -1
  11. package/dist/handover/agent-runtime-followups.md +1 -1
  12. package/dist/handover/agent-runtime-v1.md +3 -3
  13. package/dist/handover/agent-runtime-v2-loopback.md +5 -5
  14. package/dist/lightbox-Cb5-XPWV.js.map +1 -1
  15. package/dist/lightbox-Dk2ICCBB.cjs.map +1 -1
  16. package/dist/radio-group-DYvIgv3P.cjs.map +1 -1
  17. package/dist/radio-group-DchZApJl.js.map +1 -1
  18. package/dist/table-B8H-zioX.js.map +1 -1
  19. package/dist/table-ChHS4xby.cjs.map +1 -1
  20. package/dist/tree.cjs.map +1 -1
  21. package/dist/tree.js.map +1 -1
  22. package/dist/typewriter.cjs.map +1 -1
  23. package/dist/typewriter.js.map +1 -1
  24. package/dist/typography.cjs +3 -3
  25. package/dist/typography.cjs.map +1 -1
  26. package/dist/typography.js +107 -10
  27. package/dist/typography.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/area/area.component.ts +14 -0
  30. package/src/card/card.ts +1 -0
  31. package/src/chips/assist-chip.ts +11 -2
  32. package/src/chips/suggestion-chip.ts +9 -6
  33. package/src/lightbox/lightbox.ts +11 -0
  34. package/src/radio-group/radio-button.ts +1 -0
  35. package/src/table/table.ts +8 -2
  36. package/src/tree/tree.ts +1 -0
  37. package/src/typewriter/typewriter.ts +12 -0
  38. package/src/typography/typography.ts +95 -1
  39. package/types/src/area/area.component.d.ts +14 -0
  40. package/types/src/card/card.d.ts +1 -0
  41. package/types/src/chips/assist-chip.d.ts +11 -2
  42. package/types/src/chips/suggestion-chip.d.ts +9 -6
  43. package/types/src/lightbox/lightbox.d.ts +11 -0
  44. package/types/src/radio-group/radio-button.d.ts +1 -0
  45. package/types/src/table/table.d.ts +8 -2
  46. package/types/src/tree/tree.d.ts +1 -0
  47. package/types/src/typewriter/typewriter.d.ts +12 -0
  48. package/types/src/typography/typography.d.ts +33 -0
@@ -1,15 +1,67 @@
1
1
  import { TailwindElement } from '@mixins/tailwind.mixin'
2
- import { css, html } from 'lit'
2
+ import { css, html, type PropertyValues } from 'lit'
3
3
  import { customElement, property } from 'lit/decorators.js'
4
4
  import { createRef, ref } from 'lit/directives/ref.js'
5
+ import { html as staticHtml, literal } from 'lit/static-html.js'
5
6
  import { fromEvent } from 'rxjs'
6
7
  import { filter, tap, takeUntil } from 'rxjs/operators'
7
8
 
9
+ /**
10
+ * Preset → (type, token) shorthand. Saves the two-decision-per-text-node
11
+ * fatigue that 50+ typography nodes in a single page cause.
12
+ */
13
+ export type TypographyPreset =
14
+ | 'display' | 'display-lg' | 'display-md' | 'display-sm'
15
+ | 'heading-lg' | 'heading-md' | 'heading-sm'
16
+ | 'title-lg' | 'title-md' | 'title-sm'
17
+ | 'body-lg' | 'body-md' | 'body-sm'
18
+ | 'label-lg' | 'label-md' | 'label-sm'
19
+ | 'caption'
20
+
21
+ const PRESET_MAP: Record<TypographyPreset, { type: string; token: string }> = {
22
+ 'display': { type: 'display', token: 'lg' },
23
+ 'display-lg': { type: 'display', token: 'lg' },
24
+ 'display-md': { type: 'display', token: 'md' },
25
+ 'display-sm': { type: 'display', token: 'sm' },
26
+ 'heading-lg': { type: 'headline', token: 'lg' },
27
+ 'heading-md': { type: 'headline', token: 'md' },
28
+ 'heading-sm': { type: 'headline', token: 'sm' },
29
+ 'title-lg': { type: 'title', token: 'lg' },
30
+ 'title-md': { type: 'title', token: 'md' },
31
+ 'title-sm': { type: 'title', token: 'sm' },
32
+ 'body-lg': { type: 'body', token: 'lg' },
33
+ 'body-md': { type: 'body', token: 'md' },
34
+ 'body-sm': { type: 'body', token: 'sm' },
35
+ 'label-lg': { type: 'label', token: 'lg' },
36
+ 'label-md': { type: 'label', token: 'md' },
37
+ 'label-sm': { type: 'label', token: 'sm' },
38
+ 'caption': { type: 'label', token: 'sm' },
39
+ }
40
+
41
+ /**
42
+ * Allowed semantic tag names for the `as` prop. Closed enum so we can
43
+ * use `literal` template parts safely with `lit/static-html`.
44
+ */
45
+ export type TypographyTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div'
46
+
47
+ const TAG_LITERALS: Record<TypographyTag, ReturnType<typeof literal>> = {
48
+ h1: literal`h1`,
49
+ h2: literal`h2`,
50
+ h3: literal`h3`,
51
+ h4: literal`h4`,
52
+ h5: literal`h5`,
53
+ h6: literal`h6`,
54
+ p: literal`p`,
55
+ span: literal`span`,
56
+ div: literal`div`,
57
+ }
58
+
8
59
  // Material Design 3 typography - https://m3.material.io/styles/typography/type-scale-tokens
9
60
 
10
61
  /**
11
62
  * @element schmancy-typography
12
63
  * @slot - The text for the typography.
64
+ * @fires change - When `editable` is true, fires on blur or Enter with `detail.value` set to the new text content. Not fired when `editable` is unset (the default).
13
65
  */
14
66
  @customElement('schmancy-typography')
15
67
  export class SchmancyTypography extends TailwindElement(css`
@@ -302,6 +354,30 @@ export class SchmancyTypography extends TailwindElement(css`
302
354
  @property({ type: String, reflect: true })
303
355
  type: 'display' | 'headline' | 'title' | 'subtitle' | 'body' | 'label' = 'body'
304
356
 
357
+ /**
358
+ * Shorthand for picking a (type, token) pair in one go. When set, derives
359
+ * `type` and `token` automatically — saves the two-decisions-per-text-node
360
+ * fatigue that hits when a single page has 50+ typography nodes.
361
+ *
362
+ * @attr preset
363
+ * @type {TypographyPreset}
364
+ * @example <schmancy-typography preset="heading-md">Title</schmancy-typography>
365
+ */
366
+ @property({ type: String, reflect: true })
367
+ preset?: TypographyPreset
368
+
369
+ /**
370
+ * Render the slot wrapped in the requested semantic HTML element so screen
371
+ * readers expose the right role / heading level. Without `as`, the slot
372
+ * sits directly in the shadow root and the host is a generic element.
373
+ *
374
+ * @attr as
375
+ * @type {TypographyTag}
376
+ * @example <schmancy-typography preset="heading-md" as="h2">Section</schmancy-typography>
377
+ */
378
+ @property({ type: String, reflect: true })
379
+ as?: TypographyTag
380
+
305
381
  /**
306
382
  * @attr token - The size token.
307
383
  * @deprecated Prefer using Tailwind responsive text classes for better responsive design.
@@ -352,6 +428,17 @@ export class SchmancyTypography extends TailwindElement(css`
352
428
 
353
429
  private _editRef = createRef<HTMLDivElement>()
354
430
 
431
+ protected override willUpdate(changed: PropertyValues): void {
432
+ super.willUpdate?.(changed)
433
+ // `preset` shorthand expands to (type, token) so the existing CSS
434
+ // selectors keep matching without duplicating the size scale.
435
+ if (changed.has('preset') && this.preset && PRESET_MAP[this.preset]) {
436
+ const { type, token } = PRESET_MAP[this.preset]
437
+ this.type = type as typeof this.type
438
+ this.token = token as typeof this.token
439
+ }
440
+ }
441
+
355
442
  /** Focus and select all text in editable mode */
356
443
  selectAll() {
357
444
  const el = this._editRef.value
@@ -437,6 +524,13 @@ export class SchmancyTypography extends TailwindElement(css`
437
524
  data-placeholder=${this.placeholder ?? ''}
438
525
  ></div>`
439
526
  }
527
+ // `as` wraps the slot in the requested semantic tag so heading levels
528
+ // land in the accessibility tree. Without `as` the slot is bare and
529
+ // the host element carries the visual styling only.
530
+ if (this.as && TAG_LITERALS[this.as]) {
531
+ const tag = TAG_LITERALS[this.as]
532
+ return staticHtml`<${tag}><slot></slot></${tag}>`
533
+ }
440
534
  return html`<slot></slot>`
441
535
  }
442
536
  }
@@ -1,5 +1,19 @@
1
1
  import { RouteComponent } from './route.component';
2
2
  declare const SchmancyArea_base: CustomElementConstructor & import("@mixins/index").Constructor<import("lit").LitElement> & import("@mixins/index").Constructor<import("@mixins/index").IBaseMixin>;
3
+ /**
4
+ * Router outlet — renders the active route's component for the named area. Drives the schmancy router via the `area` service.
5
+ *
6
+ * @element schmancy-area
7
+ * @summary Mount once per "addressable region" of the app (typically the main content area). Use the imperative `area.push({ area, component, params })` service to navigate. Multiple named areas can coexist on a page (e.g. main content + a sheet).
8
+ * @example
9
+ * <schmancy-area name="main"></schmancy-area>
10
+ * <script>
11
+ * import { area } from '@mhmo91/schmancy';
12
+ * area.push({ area: 'main', component: MyDashboardView, params: { id: 42 } });
13
+ * </script>
14
+ * @platform div - Routing outlet. Degrades to an empty div if the tag never registers — routing is lost but the page stays accessible.
15
+ * @fires redirect - When the area resolves a route to a different destination (programmatic redirect). `detail.from` and `detail.to` are the route names.
16
+ */
3
17
  export declare class SchmancyArea extends SchmancyArea_base {
4
18
  /**
5
19
  * The name of the router outlet
@@ -17,6 +17,7 @@ declare const SchmancyCard_base: import("@mixins/index").Constructor<CustomEleme
17
17
  * </schmancy-card-action>
18
18
  * </schmancy-card>
19
19
  * @platform div - Styled `<div>`; becomes an `<a>` when `href` is set so the whole card is a single interactive surface. Degrades to a plain div/a if the tag never registers.
20
+ * @fires schmancy-click - When an interactive card is clicked or activated via keyboard. `detail.value` echoes the card's `type`. Only fires when `interactive` is set.
20
21
  */
21
22
  export default class SchmancyCard extends SchmancyCard_base {
22
23
  protected static shadowRootOptions: {
@@ -1,8 +1,17 @@
1
1
  import { LitElement } from 'lit';
2
2
  declare const SchmancyAssistChip_base: import("../../mixins").Constructor<CustomElementConstructor> & import("../../mixins").Constructor<import("@mixins/tailwind.mixin").ITailwindElementMixin> & import("../../mixins").Constructor<LitElement> & import("../../mixins").Constructor<import("../../mixins").IBaseMixin>;
3
3
  /**
4
- * Assist chip component - prompts user actions like opening calendar events or sharing content
5
- * Pure Schmancy implementation with Tailwind CSS and RxJS state management
4
+ * Assist chip single-tap trigger for a contextual action (open calendar event, share content, jump to related view). Distinct from filter and input chips: assist chips have no selected state; clicking fires `action`.
5
+ *
6
+ * @element schmancy-assist-chip
7
+ * @summary Use for "do this thing" suggestions surfaced in context (next to a date, after a recipient list, near a long description). Pair with schmancy-icon for the leading glyph.
8
+ * @example
9
+ * <schmancy-assist-chip @action=${(e) => share(e.detail.value)}>
10
+ * <schmancy-icon slot="icon">share</schmancy-icon>
11
+ * Share
12
+ * </schmancy-assist-chip>
13
+ * @platform button click - Material 3 assist-chip semantics. Degrades to a plain `<button>` if the tag never registers.
14
+ * @fires action - When the chip is clicked or activated via keyboard. `detail.value` echoes the chip's `value` attribute.
6
15
  */
7
16
  export declare class SchmancyAssistChip extends SchmancyAssistChip_base {
8
17
  /** Value identifier for the chip */
@@ -1,13 +1,16 @@
1
1
  import { LitElement } from 'lit';
2
2
  declare const SchmancySuggestionChip_base: import("../../mixins").Constructor<CustomElementConstructor> & import("../../mixins").Constructor<import("@mixins/tailwind.mixin").ITailwindElementMixin> & import("../../mixins").Constructor<LitElement> & import("../../mixins").Constructor<import("../../mixins").IBaseMixin>;
3
3
  /**
4
- * Suggestion chip component - provides contextual recommendations to users
4
+ * Suggestion chip single-tap insertion of a recommended value. Distinct from filter chips (no selected state) and assist chips (assist triggers an action; suggestion offers a value the user can pick).
5
5
  *
6
- * IMPORTANT: Suggestion chips do NOT have a selected state. They are designed to
7
- * provide suggestions and recommendations that trigger actions when clicked.
8
- * Unlike filter chips, they cannot be toggled on/off.
9
- *
10
- * Pure Schmancy implementation with Tailwind CSS and RxJS state management
6
+ * @element schmancy-suggestion-chip
7
+ * @summary Use for "would you also like to…" prompts above a search input or below a message thread. Click fires `action` with the chip's `value` so the parent can insert it into a field or trigger a search.
8
+ * @example
9
+ * <schmancy-suggestion-chip value="yesterday" @action=${(e) => setRange(e.detail.value)}>
10
+ * Yesterday
11
+ * </schmancy-suggestion-chip>
12
+ * @platform button click - Material 3 suggestion-chip semantics. Degrades to a plain `<button>` if the tag never registers.
13
+ * @fires action - When the chip is clicked or activated via keyboard. `detail.value` echoes the chip's `value` attribute.
11
14
  */
12
15
  export declare class SchmancySuggestionChip extends SchmancySuggestionChip_base {
13
16
  /** Value identifier for the chip */
@@ -1,5 +1,16 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  declare const SchmancyLightbox_base: CustomElementConstructor & import("@mixins/index").Constructor<import("lit").LitElement> & import("@mixins/index").Constructor<import("@mixins/index").IBaseMixin>;
3
+ /**
4
+ * Image lightbox — thumbnail grid that opens to a full-screen viewer on click, with keyboard navigation between images.
5
+ *
6
+ * @element schmancy-lightbox
7
+ * @summary Drop-in for galleries / image lists where each thumbnail should expand to fill the viewport. Pass an `images` array of `{ src, alt, caption? }`.
8
+ * @example
9
+ * <schmancy-lightbox .images=${[{ src: '/a.jpg', alt: 'A' }, { src: '/b.jpg', alt: 'B' }]}></schmancy-lightbox>
10
+ * @platform dialog close - Modal full-screen viewer with keyboard navigation. Degrades to a plain image grid if the tag never registers.
11
+ * @fires change - When the active image index changes (next/prev). `detail.index` is the new active image's position in the array.
12
+ * @fires close - When the viewer is dismissed (ESC, backdrop click, close button).
13
+ */
3
14
  export declare class SchmancyLightbox extends SchmancyLightbox_base {
4
15
  src: string;
5
16
  images: string[];
@@ -10,6 +10,7 @@ declare const RadioButton_base: import("@mixins/index").Constructor<import("@mix
10
10
  * <schmancy-radio-button value="pro" checked>Pro</schmancy-radio-button>
11
11
  * </schmancy-radio-group>
12
12
  * @platform radio change - Schmancy-skinned `<input type="radio">` semantics. Degrades to native radio if the tag never registers.
13
+ * @fires radio-button-click - Internal event consumed by the parent schmancy-radio-group; `detail.value` is the clicked button's value. Listen on schmancy-radio-group for the public `change` event instead of subscribing here.
13
14
  *
14
15
  * @prop {string} name - Name attribute for grouping radio buttons
15
16
  * @prop {string} value - Value of this radio button
@@ -17,9 +17,15 @@ export interface RowEventDetail<T> {
17
17
  export type SortDirection = 'asc' | 'desc' | null;
18
18
  declare const SchmancyDataTable_base: CustomElementConstructor & import("../../mixins").Constructor<import("lit").LitElement> & import("../../mixins").Constructor<import("../../mixins").IBaseMixin>;
19
19
  /**
20
- * SchmancyDataTable is a generic data table component.
21
- * It supports sorting, filtering, and custom rendering of rows.
20
+ * Generic data table typed columns, optional sort, custom renderers per column. Pass `data` (array) and `columns` (TableColumn descriptors).
22
21
  *
22
+ * @element schmancy-table
23
+ * @summary Use for tabular data where each column has a known shape. Pair with `<schmancy-table-row>` for the per-row interaction surface. Sort by setting `sortable: true` on a column descriptor; the table emits `sort-change` so the parent can re-fetch / re-sort in the data layer if needed.
24
+ * @example
25
+ * <schmancy-table .data=${rows} .columns=${[{ name: 'Name', key: 'name' }, { name: 'Status', key: 'status' }]}></schmancy-table>
26
+ * @platform table - Renders an accessible table with `<lit-virtualizer>` for large datasets. Degrades to a styled `<table>` if the tag never registers.
27
+ * @fires click - When a data row is activated. `detail.item` is the row's source object, `detail.index` is the position in the data array.
28
+ * @fires sort-change - When the user toggles a column sort. `detail.column` is the column key, `detail.direction` is `'asc' | 'desc' | null`.
23
29
  */
24
30
  export declare class SchmancyDataTable<T extends Record<string, any> = any> extends SchmancyDataTable_base {
25
31
  columns: TableColumn<T>[];
@@ -15,6 +15,7 @@ declare const SchmancyTree_base: import("@mixins/index").Constructor<CustomEleme
15
15
  * @platform details toggle - Recursive `<details>`-like disclosure. Degrades to a plain nested list if the tag never registers — loses expand/collapse but stays navigable.
16
16
  * @slot root - The root element of the tree
17
17
  * @slot - The children of the tree
18
+ * @fires toggle - When the root toggler or chevron is clicked. Fires before the open state flips; the host's `open` property reflects the new state on the next animation frame.
18
19
  */
19
20
  export declare class SchmancyTree extends SchmancyTree_base {
20
21
  /**
@@ -1,5 +1,17 @@
1
1
  import { TemplateResult } from 'lit';
2
2
  declare const TypewriterElement_base: CustomElementConstructor & import("@mixins/index").Constructor<import("lit").LitElement> & import("@mixins/index").Constructor<import("@mixins/index").IBaseMixin>;
3
+ /**
4
+ * Typewriter effect — animates text typing/deletion with a cursor. Wraps the TypeIt library, lazy-loaded on first render.
5
+ *
6
+ * @element schmancy-typewriter
7
+ * @summary Drop string content as the default slot or use `<p>` / `<span>` with `cycle="A|B|C"` attribute children for cycling phrases. Set `loop` for infinite cycling, `once` to remember completion across sessions via sessionStorage.
8
+ * @example
9
+ * <schmancy-typewriter speed="35" cursor-char="|">
10
+ * Hello, world.
11
+ * </schmancy-typewriter>
12
+ * @platform span - Animated text container. Degrades to its raw text content if the tag never registers — animation is lost but content stays visible.
13
+ * @fires typeit-complete - When the animation finishes typing all content. Fires after the final `afterComplete` callback in the underlying TypeIt instance.
14
+ */
3
15
  export declare class TypewriterElement extends TypewriterElement_base {
4
16
  /**
5
17
  * Typing speed in milliseconds per character.
@@ -1,7 +1,19 @@
1
+ import { type PropertyValues } from 'lit';
2
+ /**
3
+ * Preset → (type, token) shorthand. Saves the two-decision-per-text-node
4
+ * fatigue that 50+ typography nodes in a single page cause.
5
+ */
6
+ export type TypographyPreset = 'display' | 'display-lg' | 'display-md' | 'display-sm' | 'heading-lg' | 'heading-md' | 'heading-sm' | 'title-lg' | 'title-md' | 'title-sm' | 'body-lg' | 'body-md' | 'body-sm' | 'label-lg' | 'label-md' | 'label-sm' | 'caption';
7
+ /**
8
+ * Allowed semantic tag names for the `as` prop. Closed enum so we can
9
+ * use `literal` template parts safely with `lit/static-html`.
10
+ */
11
+ export type TypographyTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div';
1
12
  declare const SchmancyTypography_base: import("../../mixins").Constructor<CustomElementConstructor> & import("../../mixins").Constructor<import("@mixins/tailwind.mixin").ITailwindElementMixin> & import("../../mixins").Constructor<import("lit").LitElement> & import("../../mixins").Constructor<import("../../mixins").IBaseMixin>;
2
13
  /**
3
14
  * @element schmancy-typography
4
15
  * @slot - The text for the typography.
16
+ * @fires change - When `editable` is true, fires on blur or Enter with `detail.value` set to the new text content. Not fired when `editable` is unset (the default).
5
17
  */
6
18
  export declare class SchmancyTypography extends SchmancyTypography_base {
7
19
  static shadowRootOptions: ShadowRootInit;
@@ -11,6 +23,26 @@ export declare class SchmancyTypography extends SchmancyTypography_base {
11
23
  * @type {'display' | 'headline' | 'title' | 'subtitle' | 'body' | 'label'}
12
24
  */
13
25
  type: 'display' | 'headline' | 'title' | 'subtitle' | 'body' | 'label';
26
+ /**
27
+ * Shorthand for picking a (type, token) pair in one go. When set, derives
28
+ * `type` and `token` automatically — saves the two-decisions-per-text-node
29
+ * fatigue that hits when a single page has 50+ typography nodes.
30
+ *
31
+ * @attr preset
32
+ * @type {TypographyPreset}
33
+ * @example <schmancy-typography preset="heading-md">Title</schmancy-typography>
34
+ */
35
+ preset?: TypographyPreset;
36
+ /**
37
+ * Render the slot wrapped in the requested semantic HTML element so screen
38
+ * readers expose the right role / heading level. Without `as`, the slot
39
+ * sits directly in the shadow root and the host is a generic element.
40
+ *
41
+ * @attr as
42
+ * @type {TypographyTag}
43
+ * @example <schmancy-typography preset="heading-md" as="h2">Section</schmancy-typography>
44
+ */
45
+ as?: TypographyTag;
14
46
  /**
15
47
  * @attr token - The size token.
16
48
  * @deprecated Prefer using Tailwind responsive text classes for better responsive design.
@@ -49,6 +81,7 @@ export declare class SchmancyTypography extends SchmancyTypography_base {
49
81
  /** Placeholder shown when editable and empty */
50
82
  placeholder: string;
51
83
  private _editRef;
84
+ protected willUpdate(changed: PropertyValues): void;
52
85
  /** Focus and select all text in editable mode */
53
86
  selectAll(): void;
54
87
  connectedCallback(): void;