@orange-halo/components 1.0.0

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 (138) hide show
  1. package/custom-elements.json +186 -0
  2. package/dist/base.d.ts +30 -0
  3. package/dist/base.d.ts.map +1 -0
  4. package/dist/base.js +78 -0
  5. package/dist/base.js.map +1 -0
  6. package/dist/index.d.ts +83 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +72 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/oh-accordion.d.ts +47 -0
  11. package/dist/oh-accordion.d.ts.map +1 -0
  12. package/dist/oh-accordion.js +387 -0
  13. package/dist/oh-accordion.js.map +1 -0
  14. package/dist/oh-alert.d.ts +48 -0
  15. package/dist/oh-alert.d.ts.map +1 -0
  16. package/dist/oh-alert.js +343 -0
  17. package/dist/oh-alert.js.map +1 -0
  18. package/dist/oh-badge.d.ts +38 -0
  19. package/dist/oh-badge.d.ts.map +1 -0
  20. package/dist/oh-badge.js +176 -0
  21. package/dist/oh-badge.js.map +1 -0
  22. package/dist/oh-breadcrumb.d.ts +39 -0
  23. package/dist/oh-breadcrumb.d.ts.map +1 -0
  24. package/dist/oh-breadcrumb.js +277 -0
  25. package/dist/oh-breadcrumb.js.map +1 -0
  26. package/dist/oh-button.d.ts +62 -0
  27. package/dist/oh-button.d.ts.map +1 -0
  28. package/dist/oh-button.figma.d.ts +2 -0
  29. package/dist/oh-button.figma.d.ts.map +1 -0
  30. package/dist/oh-button.figma.js +20 -0
  31. package/dist/oh-button.figma.js.map +1 -0
  32. package/dist/oh-button.js +490 -0
  33. package/dist/oh-button.js.map +1 -0
  34. package/dist/oh-card.d.ts +44 -0
  35. package/dist/oh-card.d.ts.map +1 -0
  36. package/dist/oh-card.js +340 -0
  37. package/dist/oh-card.js.map +1 -0
  38. package/dist/oh-checkbox-group.d.ts +39 -0
  39. package/dist/oh-checkbox-group.d.ts.map +1 -0
  40. package/dist/oh-checkbox-group.figma.d.ts +2 -0
  41. package/dist/oh-checkbox-group.figma.d.ts.map +1 -0
  42. package/dist/oh-checkbox-group.figma.js +24 -0
  43. package/dist/oh-checkbox-group.figma.js.map +1 -0
  44. package/dist/oh-checkbox-group.js +309 -0
  45. package/dist/oh-checkbox-group.js.map +1 -0
  46. package/dist/oh-checkbox.d.ts +50 -0
  47. package/dist/oh-checkbox.d.ts.map +1 -0
  48. package/dist/oh-checkbox.js +315 -0
  49. package/dist/oh-checkbox.js.map +1 -0
  50. package/dist/oh-cluster.d.ts +38 -0
  51. package/dist/oh-cluster.d.ts.map +1 -0
  52. package/dist/oh-cluster.js +141 -0
  53. package/dist/oh-cluster.js.map +1 -0
  54. package/dist/oh-container.d.ts +38 -0
  55. package/dist/oh-container.d.ts.map +1 -0
  56. package/dist/oh-container.js +116 -0
  57. package/dist/oh-container.js.map +1 -0
  58. package/dist/oh-drawer.d.ts +66 -0
  59. package/dist/oh-drawer.d.ts.map +1 -0
  60. package/dist/oh-drawer.js +284 -0
  61. package/dist/oh-drawer.js.map +1 -0
  62. package/dist/oh-footer.d.ts +40 -0
  63. package/dist/oh-footer.d.ts.map +1 -0
  64. package/dist/oh-footer.js +112 -0
  65. package/dist/oh-footer.js.map +1 -0
  66. package/dist/oh-grid.d.ts +40 -0
  67. package/dist/oh-grid.d.ts.map +1 -0
  68. package/dist/oh-grid.js +168 -0
  69. package/dist/oh-grid.js.map +1 -0
  70. package/dist/oh-hero.d.ts +28 -0
  71. package/dist/oh-hero.d.ts.map +1 -0
  72. package/dist/oh-hero.js +242 -0
  73. package/dist/oh-hero.js.map +1 -0
  74. package/dist/oh-icon.d.ts +44 -0
  75. package/dist/oh-icon.d.ts.map +1 -0
  76. package/dist/oh-icon.js +321 -0
  77. package/dist/oh-icon.js.map +1 -0
  78. package/dist/oh-input.d.ts +56 -0
  79. package/dist/oh-input.d.ts.map +1 -0
  80. package/dist/oh-input.figma.d.ts +2 -0
  81. package/dist/oh-input.figma.d.ts.map +1 -0
  82. package/dist/oh-input.figma.js +36 -0
  83. package/dist/oh-input.figma.js.map +1 -0
  84. package/dist/oh-input.js +320 -0
  85. package/dist/oh-input.js.map +1 -0
  86. package/dist/oh-link.d.ts +45 -0
  87. package/dist/oh-link.d.ts.map +1 -0
  88. package/dist/oh-link.js +392 -0
  89. package/dist/oh-link.js.map +1 -0
  90. package/dist/oh-modal.d.ts +54 -0
  91. package/dist/oh-modal.d.ts.map +1 -0
  92. package/dist/oh-modal.js +450 -0
  93. package/dist/oh-modal.js.map +1 -0
  94. package/dist/oh-navbar.d.ts +49 -0
  95. package/dist/oh-navbar.d.ts.map +1 -0
  96. package/dist/oh-navbar.js +185 -0
  97. package/dist/oh-navbar.js.map +1 -0
  98. package/dist/oh-progress.d.ts +56 -0
  99. package/dist/oh-progress.d.ts.map +1 -0
  100. package/dist/oh-progress.js +299 -0
  101. package/dist/oh-progress.js.map +1 -0
  102. package/dist/oh-radio-group.d.ts +43 -0
  103. package/dist/oh-radio-group.d.ts.map +1 -0
  104. package/dist/oh-radio-group.figma.d.ts +2 -0
  105. package/dist/oh-radio-group.figma.d.ts.map +1 -0
  106. package/dist/oh-radio-group.figma.js +22 -0
  107. package/dist/oh-radio-group.figma.js.map +1 -0
  108. package/dist/oh-radio-group.js +324 -0
  109. package/dist/oh-radio-group.js.map +1 -0
  110. package/dist/oh-radio.d.ts +50 -0
  111. package/dist/oh-radio.d.ts.map +1 -0
  112. package/dist/oh-radio.js +314 -0
  113. package/dist/oh-radio.js.map +1 -0
  114. package/dist/oh-select.d.ts +82 -0
  115. package/dist/oh-select.d.ts.map +1 -0
  116. package/dist/oh-select.js +638 -0
  117. package/dist/oh-select.js.map +1 -0
  118. package/dist/oh-skip-link.d.ts +37 -0
  119. package/dist/oh-skip-link.d.ts.map +1 -0
  120. package/dist/oh-skip-link.js +145 -0
  121. package/dist/oh-skip-link.js.map +1 -0
  122. package/dist/oh-stack.d.ts +36 -0
  123. package/dist/oh-stack.d.ts.map +1 -0
  124. package/dist/oh-stack.js +112 -0
  125. package/dist/oh-stack.js.map +1 -0
  126. package/dist/oh-tabs.d.ts +85 -0
  127. package/dist/oh-tabs.d.ts.map +1 -0
  128. package/dist/oh-tabs.js +417 -0
  129. package/dist/oh-tabs.js.map +1 -0
  130. package/dist/oh-toggle.d.ts +51 -0
  131. package/dist/oh-toggle.d.ts.map +1 -0
  132. package/dist/oh-toggle.js +219 -0
  133. package/dist/oh-toggle.js.map +1 -0
  134. package/dist/styles/typography.d.ts +15 -0
  135. package/dist/styles/typography.d.ts.map +1 -0
  136. package/dist/styles/typography.js +235 -0
  137. package/dist/styles/typography.js.map +1 -0
  138. package/package.json +140 -0
@@ -0,0 +1,392 @@
1
+ /**
2
+ * oh-link
3
+ *
4
+ * A warm, playful link with retro-inspired styling.
5
+ * Two variants: inline (for body text) and standalone (for CTAs).
6
+ *
7
+ * DESIGN DECISIONS:
8
+ * ─────────────────
9
+ * 1. INLINE VARIANT
10
+ * - Dotted underline (quirky, retro feel)
11
+ * - Becomes solid on hover
12
+ * - Warm marmalade color
13
+ * - Subtle but distinctive
14
+ *
15
+ * 2. STANDALONE VARIANT
16
+ * - Bolder presence for CTAs
17
+ * - Offset shadow on hover (mini sticker effect)
18
+ * - Lift animation like other components
19
+ * - Arrow icon option
20
+ *
21
+ * 3. ACCESSIBILITY
22
+ * - Underline always visible (not color-only)
23
+ * - Clear focus state
24
+ * - Proper contrast ratios
25
+ *
26
+ * @element oh-link
27
+ */
28
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
29
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
30
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
31
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
32
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
33
+ };
34
+ import { html, css, nothing } from "lit";
35
+ import { customElement, property } from "lit/decorators.js";
36
+ import { OhElement, baseStyles } from "./base.js";
37
+ let OhLink = class OhLink extends OhElement {
38
+ constructor() {
39
+ super(...arguments);
40
+ this.href = "";
41
+ this.target = "";
42
+ this.rel = "";
43
+ this.variant = "inline";
44
+ this.arrow = false;
45
+ this.inverse = false;
46
+ }
47
+ static { this.styles = [
48
+ baseStyles,
49
+ css `
50
+ /* ═══════════════════════════════════════════════════════════════
51
+ ORANGE HALO LINK
52
+ Warm • Playful • Retro-inspired
53
+ ═══════════════════════════════════════════════════════════════ */
54
+
55
+ :host {
56
+ display: inline;
57
+ }
58
+
59
+ .link {
60
+ font-family: var(--oh-font-family-sans);
61
+ color: var(--oh-color-brand-primary);
62
+ text-decoration: none;
63
+ cursor: pointer;
64
+ position: relative;
65
+ }
66
+
67
+ /* ═══════════════════════════════════════════════════════════════
68
+ LINK TEXT WRAPPER
69
+ Uses pseudo-element for animated underline
70
+ ═══════════════════════════════════════════════════════════════ */
71
+
72
+ .link__text {
73
+ position: relative;
74
+ text-decoration: none;
75
+ }
76
+
77
+ /* Dashed underline via pseudo-element (animatable) */
78
+ .link__text::after {
79
+ content: '';
80
+ position: absolute;
81
+ left: 0;
82
+ right: 0;
83
+ bottom: 0;
84
+ height: 2px;
85
+ background: repeating-linear-gradient(
86
+ to right,
87
+ var(--oh-color-brand-primary) 0,
88
+ var(--oh-color-brand-primary) 4px,
89
+ transparent 4px,
90
+ transparent 8px
91
+ );
92
+ transform-origin: right;
93
+ transform: scaleX(1);
94
+ transition: transform var(--oh-motion-slow) ease;
95
+ }
96
+
97
+ /* ═══════════════════════════════════════════════════════════════
98
+ INLINE VARIANT
99
+ Dashed underline shrinks right-to-left on hover
100
+ ═══════════════════════════════════════════════════════════════ */
101
+
102
+ .link--inline {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ text-decoration: none;
106
+ }
107
+
108
+ .link--inline:hover .link__text::after {
109
+ transform: scaleX(0);
110
+ }
111
+
112
+ .link--inline:active .link__text::after {
113
+ transform: scaleX(0);
114
+ }
115
+
116
+ /* Focus: solid underline + subtle background */
117
+ .link--inline:focus {
118
+ outline: 2px solid transparent;
119
+ outline-offset: 2px;
120
+ background-color: var(--oh-focus-glow-color);
121
+ border-radius: 2px;
122
+ padding: 0 2px;
123
+ margin: 0 -2px;
124
+ }
125
+
126
+ .link--inline:focus .link__text::after {
127
+ /* Solid underline on focus */
128
+ background: var(--oh-color-brand-primary);
129
+ height: 3px;
130
+ transform: scaleX(1);
131
+ }
132
+
133
+ /* Remove background for mouse users (click focus) */
134
+ .link--inline:focus:not(:focus-visible) {
135
+ background-color: transparent;
136
+ }
137
+
138
+ .link--inline:focus:not(:focus-visible) .link__text::after {
139
+ background: repeating-linear-gradient(
140
+ to right,
141
+ var(--oh-color-brand-primary) 0,
142
+ var(--oh-color-brand-primary) 4px,
143
+ transparent 4px,
144
+ transparent 8px
145
+ );
146
+ height: 2px;
147
+ }
148
+
149
+ /* ═══════════════════════════════════════════════════════════════
150
+ STANDALONE VARIANT
151
+ CTA-style with hover lift, dashed underline shrinks on hover
152
+ ═══════════════════════════════════════════════════════════════ */
153
+
154
+ .link--standalone {
155
+ display: inline-flex;
156
+ align-items: center;
157
+ gap: var(--oh-spacing-2);
158
+ font-weight: var(--oh-font-weight-semibold);
159
+ font-size: var(--oh-font-size-lg);
160
+ text-decoration: none;
161
+ padding: var(--oh-spacing-1) 0;
162
+ }
163
+
164
+ .link--standalone:hover .link__text::after {
165
+ transform: scaleX(0);
166
+ }
167
+
168
+ .link--standalone:active .link__text::after {
169
+ transform: scaleX(0);
170
+ }
171
+
172
+ /* Focus: solid underline + background */
173
+ .link--standalone:focus {
174
+ outline: 2px solid transparent;
175
+ outline-offset: 2px;
176
+ background-color: var(--oh-focus-glow-color);
177
+ border-radius: var(--oh-radius-xs);
178
+ padding: var(--oh-spacing-1) var(--oh-spacing-2);
179
+ margin: 0 calc(-1 * var(--oh-spacing-2));
180
+ }
181
+
182
+ .link--standalone:focus .link__text::after {
183
+ background: var(--oh-color-brand-primary);
184
+ height: 3px;
185
+ transform: scaleX(1);
186
+ }
187
+
188
+ /* Remove background for mouse users (click focus) */
189
+ .link--standalone:focus:not(:focus-visible) {
190
+ background-color: transparent;
191
+ padding: var(--oh-spacing-1) 0;
192
+ margin: 0;
193
+ }
194
+
195
+ .link--standalone:focus:not(:focus-visible) .link__text::after {
196
+ background: repeating-linear-gradient(
197
+ to right,
198
+ var(--oh-color-brand-primary) 0,
199
+ var(--oh-color-brand-primary) 4px,
200
+ transparent 4px,
201
+ transparent 8px
202
+ );
203
+ height: 2px;
204
+ }
205
+
206
+ /* ═══════════════════════════════════════════════════════════════
207
+ ARROW ICON
208
+ Size matches line-height for visual balance
209
+ ═══════════════════════════════════════════════════════════════ */
210
+
211
+ .link__arrow {
212
+ width: 1lh;
213
+ height: 1lh;
214
+ transition: transform var(--oh-motion-snappy) ease;
215
+ }
216
+
217
+ .link--standalone:hover .link__arrow {
218
+ transform: translateX(3px);
219
+ }
220
+
221
+ /* ═══════════════════════════════════════════════════════════════
222
+ EXTERNAL LINK ICON
223
+ Required for accessibility when opening new window
224
+ Size matches line-height for visual balance
225
+ ═══════════════════════════════════════════════════════════════ */
226
+
227
+ .link__external {
228
+ width: 1em;
229
+ height: 1em;
230
+ margin-left: 0.25em;
231
+ flex-shrink: 0;
232
+ }
233
+
234
+ /* ═══════════════════════════════════════════════════════════════
235
+ VISUALLY HIDDEN (for screen readers)
236
+ ═══════════════════════════════════════════════════════════════ */
237
+
238
+ .visually-hidden {
239
+ position: absolute;
240
+ width: 1px;
241
+ height: 1px;
242
+ padding: 0;
243
+ margin: -1px;
244
+ overflow: hidden;
245
+ clip: rect(0, 0, 0, 0);
246
+ white-space: nowrap;
247
+ border: 0;
248
+ }
249
+
250
+ /* ═══════════════════════════════════════════════════════════════
251
+ VISITED STATE
252
+ Same as default for consistent appearance
253
+ ═══════════════════════════════════════════════════════════════ */
254
+
255
+ .link:visited {
256
+ color: var(--oh-color-brand-primary);
257
+ }
258
+
259
+ /* ═══════════════════════════════════════════════════════════════
260
+ INVERSE VARIANT (for colored backgrounds)
261
+ Contrasting text/underline for use on brand/accent surfaces
262
+ ═══════════════════════════════════════════════════════════════ */
263
+
264
+ :host([inverse]) .link {
265
+ color: var(--oh-color-text-on-accent);
266
+ }
267
+
268
+ :host([inverse]) .link:visited {
269
+ color: var(--oh-color-text-on-accent);
270
+ }
271
+
272
+ :host([inverse]) .link__text::after {
273
+ background: repeating-linear-gradient(
274
+ to right,
275
+ var(--oh-color-text-on-accent) 0,
276
+ var(--oh-color-text-on-accent) 4px,
277
+ transparent 4px,
278
+ transparent 8px
279
+ );
280
+ }
281
+
282
+ :host([inverse]) .link--inline:focus {
283
+ background-color: rgba(0, 0, 0, 0.1);
284
+ }
285
+
286
+ :host([inverse]) .link--inline:focus .link__text::after {
287
+ background: var(--oh-color-text-on-accent);
288
+ }
289
+
290
+ :host([inverse]) .link--inline:focus:not(:focus-visible) {
291
+ background-color: transparent;
292
+ }
293
+
294
+ :host([inverse]) .link--inline:focus:not(:focus-visible) .link__text::after {
295
+ background: repeating-linear-gradient(
296
+ to right,
297
+ var(--oh-color-text-on-accent) 0,
298
+ var(--oh-color-text-on-accent) 4px,
299
+ transparent 4px,
300
+ transparent 8px
301
+ );
302
+ }
303
+
304
+ :host([inverse]) .link--standalone:focus {
305
+ background-color: rgba(0, 0, 0, 0.1);
306
+ }
307
+
308
+ :host([inverse]) .link--standalone:focus .link__text::after {
309
+ background: var(--oh-color-text-on-accent);
310
+ }
311
+
312
+ :host([inverse]) .link--standalone:focus:not(:focus-visible) {
313
+ background-color: transparent;
314
+ }
315
+
316
+ :host([inverse]) .link--standalone:focus:not(:focus-visible) .link__text::after {
317
+ background: repeating-linear-gradient(
318
+ to right,
319
+ var(--oh-color-text-on-accent) 0,
320
+ var(--oh-color-text-on-accent) 4px,
321
+ transparent 4px,
322
+ transparent 8px
323
+ );
324
+ }
325
+
326
+ /* ═══════════════════════════════════════════════════════════════
327
+ REDUCED MOTION
328
+ ═══════════════════════════════════════════════════════════════ */
329
+
330
+ @media (prefers-reduced-motion: reduce) {
331
+ .link,
332
+ .link__arrow,
333
+ .link__text::after {
334
+ transition-duration: 0.01ms !important;
335
+ }
336
+ }
337
+ `,
338
+ ]; }
339
+ render() {
340
+ const linkClasses = this.classMap({
341
+ link: true,
342
+ "link--inline": this.variant === "inline",
343
+ "link--standalone": this.variant === "standalone",
344
+ });
345
+ // Auto-add rel="noopener noreferrer" for external links
346
+ const computedRel = this.target === "_blank" && !this.rel
347
+ ? "noopener noreferrer"
348
+ : this.rel;
349
+ const isExternal = this.target === "_blank";
350
+ return html `
351
+ <a
352
+ class=${linkClasses}
353
+ href=${this.href}
354
+ target=${this.target || nothing}
355
+ rel=${computedRel || nothing}
356
+ >
357
+ <span class="link__text"><slot></slot></span>${isExternal
358
+ ? html `<svg class="link__external" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M4.25 5.5a.75.75 0 00-.75.75v8.5c0 .414.336.75.75.75h8.5a.75.75 0 00.75-.75v-4a.75.75 0 011.5 0v4A2.25 2.25 0 0112.75 17h-8.5A2.25 2.25 0 012 14.75v-8.5A2.25 2.25 0 014.25 4h5a.75.75 0 010 1.5h-5z" clip-rule="evenodd" /><path fill-rule="evenodd" d="M6.194 12.753a.75.75 0 001.06.053L16.5 4.44v2.81a.75.75 0 001.5 0v-4.5a.75.75 0 00-.75-.75h-4.5a.75.75 0 000 1.5h2.553l-9.056 8.194a.75.75 0 00-.053 1.06z" clip-rule="evenodd" /></svg><span class="visually-hidden">(opens in new tab)</span>`
359
+ : nothing}${this.variant === "standalone" && this.arrow && !isExternal
360
+ ? html `
361
+ <svg class="link__arrow" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
362
+ <path fill-rule="evenodd" d="M3 10a.75.75 0 01.75-.75h10.638L10.23 5.29a.75.75 0 111.04-1.08l5.5 5.25a.75.75 0 010 1.08l-5.5 5.25a.75.75 0 11-1.04-1.08l4.158-3.96H3.75A.75.75 0 013 10z" clip-rule="evenodd" />
363
+ </svg>
364
+ `
365
+ : nothing}
366
+ </a>
367
+ `;
368
+ }
369
+ };
370
+ __decorate([
371
+ property({ type: String })
372
+ ], OhLink.prototype, "href", void 0);
373
+ __decorate([
374
+ property({ type: String })
375
+ ], OhLink.prototype, "target", void 0);
376
+ __decorate([
377
+ property({ type: String })
378
+ ], OhLink.prototype, "rel", void 0);
379
+ __decorate([
380
+ property({ type: String })
381
+ ], OhLink.prototype, "variant", void 0);
382
+ __decorate([
383
+ property({ type: Boolean })
384
+ ], OhLink.prototype, "arrow", void 0);
385
+ __decorate([
386
+ property({ type: Boolean, reflect: true })
387
+ ], OhLink.prototype, "inverse", void 0);
388
+ OhLink = __decorate([
389
+ customElement("oh-link")
390
+ ], OhLink);
391
+ export { OhLink };
392
+ //# sourceMappingURL=oh-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-link.js","sourceRoot":"","sources":["../src/oh-link.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;;;;;AAEH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAK3C,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,SAAS;IAA9B;;QAuSL,SAAI,GAAG,EAAE,CAAC;QAGV,WAAM,GAAG,EAAE,CAAC;QAGZ,QAAG,GAAG,EAAE,CAAC;QAGT,YAAO,GAAgB,QAAQ,CAAC;QAGhC,UAAK,GAAG,KAAK,CAAC;QAGd,YAAO,GAAG,KAAK,CAAC;IAmClB,CAAC;aAxViB,WAAM,GAAG;QACvB,UAAU;QACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgSF;KACF,AAnSqB,CAmSpB;IAoBF,MAAM;QACJ,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC;YAChC,IAAI,EAAE,IAAI;YACV,cAAc,EAAE,IAAI,CAAC,OAAO,KAAK,QAAQ;YACzC,kBAAkB,EAAE,IAAI,CAAC,OAAO,KAAK,YAAY;SAClD,CAAC,CAAC;QAEH,wDAAwD;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG;YACvD,CAAC,CAAC,qBAAqB;YACvB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAEb,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC;QAE5C,OAAO,IAAI,CAAA;;gBAEC,WAAW;eACZ,IAAI,CAAC,IAAI;iBACP,IAAI,CAAC,MAAM,IAAI,OAAO;cACzB,WAAW,IAAI,OAAO;;uDAEmB,UAAU;YACvD,CAAC,CAAC,IAAI,CAAA,8lBAA8lB;YACpmB,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU;YACtE,CAAC,CAAC,IAAI,CAAA;;;;aAIH;YACH,CAAC,CAAC,OAAO;;KAEd,CAAC;IACJ,CAAC;;AAjDD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCACjB;AAGV;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCACf;AAGZ;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;mCAClB;AAGT;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCACK;AAGhC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;qCACd;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uCAC3B;AAtTL,MAAM;IADlB,aAAa,CAAC,SAAS,CAAC;GACZ,MAAM,CAyVlB"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * oh-modal
3
+ *
4
+ * A chunky, accessible modal dialog with focus trapping.
5
+ *
6
+ * DESIGN DECISIONS:
7
+ * ─────────────────
8
+ * 1. CHUNKY & LIFTED
9
+ * - 2.5px border like other components
10
+ * - Offset shadow (4px 4px) — feels like a lifted surface
11
+ * - Warm backdrop, not pure black
12
+ *
13
+ * 2. ACCESSIBLE
14
+ * - Focus trap when open
15
+ * - Escape key closes (when dismissible)
16
+ * - Focus returns to trigger on close
17
+ * - role="dialog" + aria-modal="true"
18
+ *
19
+ * 3. FLEXIBLE STRUCTURE
20
+ * - Optional heading
21
+ * - Scrollable body content
22
+ * - Optional footer slot for actions
23
+ *
24
+ * @element oh-modal
25
+ */
26
+ import { OhElement } from "./base.js";
27
+ export type ModalSize = "sm" | "md" | "lg";
28
+ export declare class OhModal extends OhElement {
29
+ static styles: import("lit").CSSResult[];
30
+ open: boolean;
31
+ heading: string;
32
+ dismissible: boolean;
33
+ size: ModalSize;
34
+ private _previousActiveElement;
35
+ private _closeButton;
36
+ connectedCallback(): void;
37
+ updated(changedProperties: Map<string, unknown>): void;
38
+ private _onOpen;
39
+ private _onClose;
40
+ private _handleKeyDown;
41
+ private _trapFocus;
42
+ private _getFocusableElements;
43
+ private _focusFirstElement;
44
+ private _handleBackdropClick;
45
+ private _requestClose;
46
+ disconnectedCallback(): void;
47
+ render(): import("lit").TemplateResult<1>;
48
+ }
49
+ declare global {
50
+ interface HTMLElementTagNameMap {
51
+ "oh-modal": OhModal;
52
+ }
53
+ }
54
+ //# sourceMappingURL=oh-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-modal.d.ts","sourceRoot":"","sources":["../src/oh-modal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,qBACa,OAAQ,SAAQ,SAAS;IACpC,OAAgB,MAAM,4BA0NpB;IAGF,IAAI,UAAS;IAGb,OAAO,SAAM;IAGb,WAAW,UAAQ;IAGnB,IAAI,EAAE,SAAS,CAAQ;IAGvB,OAAO,CAAC,sBAAsB,CAA4B;IAI1D,OAAO,CAAC,YAAY,CAAqB;IAEzC,iBAAiB;IAKjB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAU/C,OAAO,CAAC,OAAO;IAoBf,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,UAAU;IAsBlB,OAAO,CAAC,qBAAqB;IAqB7B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,aAAa;IAKrB,oBAAoB;IAMpB,MAAM;CA8DP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}