@threadlabs/looma 0.25.4 → 0.25.6

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 (71) hide show
  1. package/components/ui-card/ui-card.html +27 -2
  2. package/components/ui-checkbox/ui-checkbox.html +2 -0
  3. package/components/ui-cluster/ui-cluster.html +35 -2
  4. package/components/ui-editor-surface/ui-editor-surface.html +23 -0
  5. package/components/ui-list-item/ui-list-item.html +12 -3
  6. package/components/ui-scroll-area/ui-scroll-area.html +5 -0
  7. package/components/ui-stack/ui-stack.html +17 -1
  8. package/components/ui-text/ui-text.html +5 -0
  9. package/components/ui-textarea/ui-textarea.html +7 -0
  10. package/dist/index.js +1 -1
  11. package/package.json +1 -1
  12. package/styles/ui-card.css +24 -0
  13. package/styles/ui-cluster.css +28 -0
  14. package/styles/ui-editor-surface.css +19 -0
  15. package/styles/ui-list-item.css +11 -3
  16. package/styles/ui-scroll-area.css +4 -0
  17. package/styles/ui-stack.css +13 -0
  18. package/styles/ui-text.css +4 -0
  19. package/styles/ui-textarea.css +4 -0
  20. package/vanilla/UiCard.d.ts +1 -1
  21. package/vanilla/UiCard.js +1 -1
  22. package/vanilla/UiCheckbox.d.ts +1 -0
  23. package/vanilla/UiCheckbox.js +18 -15
  24. package/vanilla/UiCluster.d.ts +4 -1
  25. package/vanilla/UiCluster.js +10 -4
  26. package/vanilla/UiEditorSurface.d.ts +14 -0
  27. package/vanilla/UiEditorSurface.js +27 -0
  28. package/vanilla/UiListItem.d.ts +1 -0
  29. package/vanilla/UiListItem.js +4 -2
  30. package/vanilla/UiScrollArea.d.ts +1 -0
  31. package/vanilla/UiScrollArea.js +1 -1
  32. package/vanilla/UiStack.d.ts +2 -0
  33. package/vanilla/UiStack.js +8 -9
  34. package/vanilla/UiText.d.ts +1 -0
  35. package/vanilla/UiText.js +1 -1
  36. package/vanilla/UiTextarea.d.ts +1 -0
  37. package/vanilla/UiTextarea.js +4 -1
  38. package/vanilla/index.js +1 -0
  39. package/vue/UiCard.d.ts +3 -3
  40. package/vue/UiCard.vue +34 -5
  41. package/vue/UiCheckbox.d.ts +9 -0
  42. package/vue/UiCheckbox.vue +20 -0
  43. package/vue/UiCluster.d.ts +30 -3
  44. package/vue/UiCluster.vue +102 -5
  45. package/vue/UiEditorSurface.d.ts +26 -0
  46. package/vue/UiEditorSurface.js +2 -0
  47. package/vue/UiEditorSurface.vue +129 -0
  48. package/vue/UiListItem.d.ts +9 -0
  49. package/vue/UiListItem.vue +35 -4
  50. package/vue/UiScrollArea.d.ts +9 -0
  51. package/vue/UiScrollArea.vue +28 -2
  52. package/vue/UiStack.d.ts +18 -0
  53. package/vue/UiStack.vue +58 -1
  54. package/vue/UiText.d.ts +9 -0
  55. package/vue/UiText.vue +33 -0
  56. package/vue/UiTextarea.d.ts +9 -0
  57. package/vue/UiTextarea.vue +37 -2
  58. package/vue/chunks/UiCard.js +10 -3
  59. package/vue/chunks/UiCheckbox.js +25 -1
  60. package/vue/chunks/UiCluster.js +85 -3
  61. package/vue/chunks/UiEditorSurface.js +71 -0
  62. package/vue/chunks/UiListItem.js +23 -1
  63. package/vue/chunks/UiScrollArea.js +28 -2
  64. package/vue/chunks/UiStack.js +46 -1
  65. package/vue/chunks/UiText.js +43 -1
  66. package/vue/chunks/UiTextarea.js +28 -2
  67. package/vue/components.css +255 -162
  68. package/vue/editor/LoomaEditor.d.ts +12 -0
  69. package/vue/editor/index.js +7 -2
  70. package/vue/index.d.ts +1 -0
  71. package/vue/index.js +2 -1
@@ -7,8 +7,9 @@
7
7
  elevated floats above the page with a shadow, for a view's one card, such as sign-in.</prop>
8
8
  <prop name="padding" type="keyword" values="xs, sm, md, lg" default="md"
9
9
  >The space inside the card: xs is compact (0.5rem), sm is snug (0.75rem), md is the default (1.5rem), and lg is roomy (2rem).</prop>
10
- <prop name="tone" type="keyword" values="neutral, danger" default="neutral"
11
- >danger adds a soft danger surface and a strong leading edge for consequential content.</prop>
10
+ <prop name="tone" type="keyword" values="neutral, accent, info, success, warning, danger" default="neutral"
11
+ >accent, info, success and warning add a quiet semantic surface. danger retains its strong leading edge for consequential content. Tone never changes child
12
+ controls.</prop>
12
13
  <prop name="as" type="keyword" values="div, section, article, aside" default="div"
13
14
  >The native element the card renders. Choose the one that names the content: a section of a page, a self-contained article, or an aside.</prop>
14
15
  </defs>
@@ -57,6 +58,30 @@
57
58
  box-shadow: var(--ui-shadow-lg);
58
59
  }
59
60
 
61
+ :host([tone="accent"]) {
62
+ border-color: color-mix(in srgb, var(--ui-accent) 25%, var(--ui-border-default));
63
+ background: color-mix(in srgb, var(--ui-accent) 6%, var(--ui-surface-default));
64
+ }
65
+
66
+ :host([tone="info"]) {
67
+ border-color: color-mix(in srgb, var(--ui-info) 25%, var(--ui-border-default));
68
+ background: color-mix(in srgb, var(--ui-info) 6%, var(--ui-surface-default));
69
+ }
70
+
71
+ :host([tone="success"]) {
72
+ border-color: color-mix(in srgb, var(--ui-success) 25%, var(--ui-border-default));
73
+ background: color-mix(in srgb, var(--ui-success) 6%, var(--ui-surface-default));
74
+ }
75
+
76
+ :host([tone="warning"]) {
77
+ border-color: color-mix(in srgb, var(--ui-warning) 25%, var(--ui-border-default));
78
+ background: color-mix(in srgb, var(--ui-warning) 6%, var(--ui-surface-default));
79
+ }
80
+
81
+ :host([variant="subtle"]:is([tone="accent"], [tone="info"], [tone="success"], [tone="warning"])) {
82
+ border-color: transparent;
83
+ }
84
+
60
85
  :host([tone="danger"]) {
61
86
  border-color: color-mix(in srgb, var(--ui-danger) 45%, var(--ui-border-default));
62
87
  border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger);
@@ -1,5 +1,6 @@
1
1
  <template component="ui-checkbox" controller="./ui-checkbox.js">
2
2
  <defs>
3
+ <prop name="label" type="string" default="">An accessible name for a checkbox without a visible label slot. It names the native input.</prop>
3
4
  <prop name="checked" type="boolean" default="false"
4
5
  >Whether the checkbox is checked initially or when set externally. A form reset returns it to this.</prop>
5
6
  <prop name="disabled" type="boolean" default="false">Disables the native checkbox, so it cannot be toggled or focused.</prop>
@@ -29,6 +30,7 @@
29
30
  <label>
30
31
  <input
31
32
  type="checkbox"
33
+ from:aria-label="label"
32
34
  $ref="input"
33
35
  .checked="internalChecked"
34
36
  .indeterminate="indeterminate"
@@ -1,11 +1,16 @@
1
1
  <template component="ui-cluster">
2
2
  <defs>
3
+ <prop name="padding" type="keyword" values="none, s, m, l" default="none"
4
+ >Optional internal space for an action group, using the shared spacing scale.</prop>
5
+ <prop name="paddingEnd" type="keyword" values="none, s, m, l, xl" default="none"
6
+ >Optional extra space at the inline end, such as clearance beside another control. xl is 4rem.</prop>
7
+ <prop name="fixed" type="boolean" default="false">Keeps this group at its content size inside a flex layout.</prop>
3
8
  <prop name="gap" type="keyword" values="xs, s, m, l, xl"
4
9
  >Space between items, on the spacing scale: xs is 0.5rem, s 0.75rem (also the default), m 1rem, l 1.5rem, and xl 2rem. The --ui-cluster-gap custom property,
5
10
  set on the cluster itself, overrides it; set on an ancestor, it does nothing.</prop>
6
- <prop name="align" type="keyword" values="start, center, end, stretch"
11
+ <prop name="align" type="keyword" values="start, center, end, stretch, baseline"
7
12
  >How items line up within each row: center (the default) aligns their middles, start their tops, end their bottoms, and stretch makes every item as tall as
8
- its row.</prop>
13
+ its row. baseline aligns the first text baselines, including multiline columns.</prop>
9
14
  <prop name="justify" type="keyword" values="start, center, end, between"
10
15
  >Where items sit along each row: start (the default), center, end, or between, which pushes the first and last items to the ends of the row and spreads the
11
16
  spare space between them, as for a title with its actions.</prop>
@@ -33,6 +38,31 @@
33
38
  margin: 0;
34
39
  }
35
40
 
41
+ :host([fixed]) {
42
+ flex: none;
43
+ }
44
+ :host([padding="s"]) {
45
+ padding: var(--ui-space-2);
46
+ }
47
+ :host([padding="m"]) {
48
+ padding: var(--ui-space-3);
49
+ }
50
+ :host([padding="l"]) {
51
+ padding: var(--ui-space-4);
52
+ }
53
+ :host([paddingEnd="s"]) {
54
+ padding-inline-end: var(--ui-space-2);
55
+ }
56
+ :host([paddingEnd="m"]) {
57
+ padding-inline-end: var(--ui-space-3);
58
+ }
59
+ :host([paddingEnd="l"]) {
60
+ padding-inline-end: var(--ui-space-4);
61
+ }
62
+ :host([paddingEnd="xl"]) {
63
+ padding-inline-end: calc(var(--ui-space-4) * 4);
64
+ }
65
+
36
66
  :host([gap="xs"]) {
37
67
  --_layout-gap: var(--ui-space-2);
38
68
  }
@@ -54,6 +84,9 @@
54
84
  :host([align="end"]) {
55
85
  align-items: flex-end;
56
86
  }
87
+ :host([align="baseline"]) {
88
+ align-items: baseline;
89
+ }
57
90
  :host([align="stretch"]) {
58
91
  align-items: stretch;
59
92
  }
@@ -0,0 +1,23 @@
1
+ <template component="ui-editor-surface">
2
+ <defs>
3
+ <prop name="density" type="keyword" values="comfortable, compact" default="comfortable"
4
+ >The document canvas. comfortable preserves the editor's normal room and mobile toolbar clearance. compact fits a read-only excerpt to its content without
5
+ outer padding.</prop>
6
+ </defs>
7
+ <div><slot></slot></div>
8
+ <style>
9
+ :host {
10
+ display: flex;
11
+ flex-direction: column;
12
+ min-inline-size: 0;
13
+ max-inline-size: 100%;
14
+ }
15
+ /* The document renderer consumes these inherited surface settings. They do not style controls. */
16
+ :host([density="compact"]) {
17
+ --_ui-editor-content-min-height: 0px;
18
+ --_ui-editor-content-padding-block: 0px;
19
+ --_ui-editor-content-padding-inline: 0px;
20
+ --_ui-editor-mobile-bottom-space: 0px;
21
+ }
22
+ </style>
23
+ </template>
@@ -3,6 +3,9 @@
3
3
  <prop name="variant" type="keyword" values="row, card" default="row"
4
4
  >How the item is drawn. A row is flat and takes a hover surface when it is a link, for items read down a list. A card sits on a raised, bordered surface,
5
5
  for items set in a grid (a List with layout="grid"). Both have the same parts: leading, title, description, and trailing.</prop>
6
+ <prop name="leadingInteractive" type="boolean" default="false"
7
+ >Makes the leading region an independent control above the row link. Use it for a checkbox or button; keep noninteractive row icons in the title link when
8
+ combining them with a leading control.</prop>
6
9
  <prop name="wrap" type="boolean" default="false"
7
10
  >Lets the title and description wrap so explanatory text stays readable on narrow screens. Omit it for the default equal-height, one-line rows.</prop>
8
11
  <prop name="current" type="boolean" default="false"
@@ -74,11 +77,11 @@
74
77
  background: var(--ui-surface-raised);
75
78
  }
76
79
 
77
- :host:has(.title a[href]:hover) {
78
- background: var(--ui-surface-hover);
80
+ :host:where(:has(.title a[href])):hover {
81
+ background: var(--ui-selection-surface);
79
82
  }
80
83
 
81
- :host([variant="card"]):has(.title a[href]:hover) {
84
+ :host([variant="card"]):where(:has(.title a[href])):hover {
82
85
  border-color: var(--ui-border-strong);
83
86
  }
84
87
 
@@ -112,6 +115,12 @@
112
115
  color: var(--ui-selection-text);
113
116
  }
114
117
 
118
+ /* An explicitly independent leading control sits above the stretched row link. */
119
+ :host([leadingInteractive]) .leading {
120
+ position: relative;
121
+ z-index: 1;
122
+ }
123
+
115
124
  /* Trailing controls take their own clicks, above the title link's stretched hit area. */
116
125
  .trailing {
117
126
  position: relative;
@@ -1,5 +1,6 @@
1
1
  <template component="ui-scroll-area" controller="./ui-scroll-area.js">
2
2
  <defs>
3
+ <prop name="fill" type="boolean" default="false">Grows into remaining space within a flex layout while keeping content independently scrollable.</prop>
3
4
  <prop name="size" type="keyword" values="content, sm, md, lg" default="content"
4
5
  >Optional height preset. content keeps intrinsic sizing; sm fits three compact 3.125rem result rows before the overflow fade, md is 20rem, and lg is
5
6
  30rem.</prop>
@@ -12,6 +13,10 @@
12
13
  /* The controller sets each fade length from overflow and scroll position. The mask blends
13
14
  into whatever is behind the area without needing to know its colour. Before upgrade, its
14
15
  zero-length defaults leave the authored scroll area fully visible. */
16
+ :host([fill]) {
17
+ flex: 1;
18
+ }
19
+
15
20
  :host {
16
21
  display: block;
17
22
  box-sizing: border-box;
@@ -1,5 +1,7 @@
1
1
  <template component="ui-stack">
2
2
  <defs>
3
+ <prop name="fill" type="boolean" default="false">Grows into the remaining space of a flex layout and allows its scrolling children to shrink.</prop>
4
+ <prop name="height" type="number">An optional measured height in CSS pixels, for a viewport-bounded composition. Omit it to retain intrinsic sizing.</prop>
3
5
  <prop name="gap" type="keyword" values="none, xs, s, m, l, xl"
4
6
  >Space between items, on the spacing scale: none is zero, xs is 0.5rem, s 0.75rem, m 1rem (also the default), l 1.5rem, and xl 2rem. The --ui-stack-gap
5
7
  custom property, set on the stack itself, overrides it; set on an ancestor, it does nothing.</prop>
@@ -10,9 +12,14 @@
10
12
  >Where items sit along a stack that is taller than its content: start (the default), center, end, or between, which spreads the spare space between items.
11
13
  It has no effect unless the stack is given a height or stretched to one.</prop>
12
14
  </defs>
13
- <div><slot></slot></div>
15
+ <div style:--ui-stack-height="height"><slot></slot></div>
14
16
  <style>
15
17
  /* This component's hooks style the element they are set on, and never a nested one. */
18
+ @property --ui-stack-height {
19
+ syntax: "*";
20
+ inherits: false;
21
+ }
22
+
16
23
  @property --ui-stack-gap {
17
24
  syntax: "*";
18
25
  inherits: false;
@@ -29,6 +36,15 @@
29
36
  margin: 0;
30
37
  }
31
38
 
39
+ :host([fill]) {
40
+ flex: 1;
41
+ min-block-size: 0;
42
+ }
43
+ :host([height]) {
44
+ block-size: calc(var(--ui-stack-height, 0) * 1px);
45
+ min-block-size: 0;
46
+ }
47
+
32
48
  :host([gap="none"]) {
33
49
  --_layout-gap: 0px;
34
50
  }
@@ -1,5 +1,6 @@
1
1
  <template component="ui-text">
2
2
  <defs>
3
+ <prop name="grow" type="boolean" default="false">Lets this text use remaining inline space in a flex row, including when truncated.</prop>
3
4
  <prop name="font" type="keyword" values="inherit, sans" default="inherit"
4
5
  >Use sans for UI text rendered outside its original font context; inherit preserves the surrounding typeface.</prop>
5
6
  <prop name="wrap" type="keyword" values="normal, anywhere" default="normal"
@@ -39,6 +40,10 @@
39
40
  /* Running text, set on the type scale and in a tone that says what it is, so a view never styles
40
41
  text of its own. The root is a paragraph unless as= names a span, div, small, strong, label, or
41
42
  heading. */
43
+ :host([grow]) {
44
+ flex: 1;
45
+ }
46
+
42
47
  :host {
43
48
  margin: 0;
44
49
  min-inline-size: 0;
@@ -8,6 +8,8 @@
8
8
  <prop name="readonly" type="boolean" default="false">Allows selection without allowing edits.</prop>
9
9
  <prop name="required" type="boolean" default="false">Marks the control as required for form validation.</prop>
10
10
  <prop name="rows" type="integer" default="4">Initial number of visible text rows.</prop>
11
+ <prop name="maxRows" type="integer"
12
+ >Optional maximum visible rows, for a growing field in a bounded layout. Extra text scrolls inside the field. Omit it to retain unbounded growth.</prop>
11
13
  <prop name="autosize" type="boolean" default="false"
12
14
  >Grow with the text while keeping rows as the minimum visible height. Uses CSS field sizing where supported; other browsers keep the native rows
13
15
  behavior.</prop>
@@ -23,6 +25,7 @@
23
25
  from:aria-invalid="invalid"
24
26
  from:rows="rows"
25
27
  style:--_rows="rows"
28
+ style:--_max-rows="maxRows"
26
29
  ></textarea>
27
30
  <style>
28
31
  /* This component's hooks style the element they are set on, and never a nested one. */
@@ -164,6 +167,10 @@
164
167
  font-size: var(--ui-font-size-md);
165
168
  }
166
169
 
170
+ :host([maxRows]) {
171
+ max-block-size: calc(max(var(--_rows), var(--_max-rows)) * 1lh + var(--_padding-block) + var(--_padding-block) + 2px);
172
+ }
173
+
167
174
  @supports (field-sizing: content) {
168
175
  :host([autosize]) {
169
176
  field-sizing: content;