@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,284 @@
1
+ /**
2
+ * oh-drawer
3
+ *
4
+ * A slide-out drawer component for mobile navigation and side panels.
5
+ *
6
+ * DESIGN DECISIONS:
7
+ * ─────────────────
8
+ * 1. POSITIONING
9
+ * - Slides in from left or right
10
+ * - Full height, configurable width
11
+ * - Overlays content with warm backdrop
12
+ *
13
+ * 2. STYLING
14
+ * - Chunky border on the edge
15
+ * - Warm surface background
16
+ * - Smooth slide animation
17
+ *
18
+ * 3. ACCESSIBILITY
19
+ * - Focus trap when open
20
+ * - Escape key closes
21
+ * - aria-modal and role="dialog"
22
+ * - Returns focus to trigger on close
23
+ *
24
+ * @element oh-drawer
25
+ *
26
+ * @slot - Default slot for drawer content
27
+ *
28
+ * @fires oh-close - When the drawer is closed
29
+ *
30
+ * @cssprop --oh-drawer-width - Width of the drawer (default: 280px)
31
+ */
32
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
33
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
34
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
35
+ 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;
36
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
37
+ };
38
+ import { html, css } from "lit";
39
+ import { customElement, property, state, query } from "lit/decorators.js";
40
+ import { OhElement, baseStyles } from "./base.js";
41
+ import { trapFocus } from "@orange-halo/utils";
42
+ import "./oh-button.js";
43
+ import "./oh-icon.js";
44
+ let OhDrawer = class OhDrawer extends OhElement {
45
+ constructor() {
46
+ super(...arguments);
47
+ /** Whether the drawer is open */
48
+ this.open = false;
49
+ /** Position of the drawer */
50
+ this.position = "left";
51
+ /** Element that triggered the drawer (for focus return) */
52
+ this._triggerElement = null;
53
+ }
54
+ static { this.styles = [
55
+ baseStyles,
56
+ css `
57
+ :host {
58
+ display: contents;
59
+ }
60
+
61
+ /* Backdrop */
62
+ .drawer-backdrop {
63
+ position: fixed;
64
+ inset: 0;
65
+ background-color: var(--oh-color-surface-overlay);
66
+ z-index: 999;
67
+ opacity: 0;
68
+ visibility: hidden;
69
+ transition: opacity var(--oh-motion-relaxed) var(--oh-motion-ease-gentle),
70
+ visibility var(--oh-motion-relaxed) var(--oh-motion-ease-gentle);
71
+ }
72
+
73
+ .drawer-backdrop.is-open {
74
+ opacity: 1;
75
+ visibility: visible;
76
+ }
77
+
78
+ /* Drawer panel */
79
+ .drawer {
80
+ position: fixed;
81
+ top: 0;
82
+ bottom: 0;
83
+ width: var(--oh-drawer-width, 280px);
84
+ max-width: calc(100vw - 48px);
85
+ background-color: var(--oh-color-surface-base);
86
+ z-index: 1000;
87
+ display: flex;
88
+ flex-direction: column;
89
+ transition: transform var(--oh-motion-relaxed) var(--oh-motion-ease-gentle);
90
+ }
91
+
92
+ /* Left position (default) */
93
+ .drawer--left {
94
+ left: 0;
95
+ border-right: var(--oh-border-width-lg) solid var(--oh-color-border-default);
96
+ box-shadow: var(--oh-shadow-lg);
97
+ transform: translateX(-100%);
98
+ }
99
+
100
+ .drawer--left.is-open {
101
+ transform: translateX(0);
102
+ }
103
+
104
+ /* Right position */
105
+ .drawer--right {
106
+ right: 0;
107
+ border-left: var(--oh-border-width-lg) solid var(--oh-color-border-default);
108
+ box-shadow: calc(-1 * var(--oh-shadow-offset-x, 4px)) var(--oh-shadow-offset-y, 4px) 0 0 var(--oh-color-warm-dune);
109
+ transform: translateX(100%);
110
+ }
111
+
112
+ .drawer--right.is-open {
113
+ transform: translateX(0);
114
+ }
115
+
116
+ /* Header */
117
+ .drawer__header {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: space-between;
121
+ padding: var(--oh-spacing-4);
122
+ border-bottom: var(--oh-border-width-md) solid var(--oh-color-border-default);
123
+ flex-shrink: 0;
124
+ }
125
+
126
+ .drawer__title {
127
+ font-family: var(--oh-font-family-sans);
128
+ font-size: var(--oh-font-size-lg);
129
+ font-weight: var(--oh-font-weight-semibold);
130
+ color: var(--oh-color-text-primary);
131
+ margin: 0;
132
+ }
133
+
134
+ /* Content */
135
+ .drawer__content {
136
+ flex: 1;
137
+ overflow-y: auto;
138
+ padding: var(--oh-spacing-4);
139
+ }
140
+
141
+ /* Reduced motion */
142
+ @media (prefers-reduced-motion: reduce) {
143
+ .drawer-backdrop,
144
+ .drawer {
145
+ transition: none;
146
+ }
147
+ }
148
+ `,
149
+ ]; }
150
+ connectedCallback() {
151
+ super.connectedCallback();
152
+ this._handleKeydown = this._handleKeydown.bind(this);
153
+ }
154
+ disconnectedCallback() {
155
+ super.disconnectedCallback();
156
+ document.removeEventListener("keydown", this._handleKeydown);
157
+ this._cleanupFocusTrap?.();
158
+ }
159
+ updated(changedProperties) {
160
+ if (changedProperties.has("open")) {
161
+ if (this.open) {
162
+ this._onOpen();
163
+ }
164
+ else {
165
+ this._onClose();
166
+ }
167
+ }
168
+ }
169
+ _onOpen() {
170
+ // Store the trigger element for focus return
171
+ this._triggerElement = document.activeElement;
172
+ // Prevent body scroll
173
+ document.body.style.overflow = "hidden";
174
+ // Add keydown listener
175
+ document.addEventListener("keydown", this._handleKeydown);
176
+ // Set up focus trap after render
177
+ requestAnimationFrame(() => {
178
+ if (this._drawer) {
179
+ this._cleanupFocusTrap = trapFocus(this._drawer);
180
+ // Focus the close button
181
+ const closeBtn = this._drawer.querySelector("oh-button");
182
+ closeBtn?.focus();
183
+ }
184
+ });
185
+ }
186
+ _onClose() {
187
+ // Restore body scroll
188
+ document.body.style.overflow = "";
189
+ // Remove keydown listener
190
+ document.removeEventListener("keydown", this._handleKeydown);
191
+ // Clean up focus trap
192
+ this._cleanupFocusTrap?.();
193
+ this._cleanupFocusTrap = undefined;
194
+ // Return focus to trigger
195
+ this._triggerElement?.focus();
196
+ this._triggerElement = null;
197
+ }
198
+ _handleKeydown(event) {
199
+ if (event.key === "Escape" && this.open) {
200
+ event.preventDefault();
201
+ this._close();
202
+ }
203
+ }
204
+ _close() {
205
+ this.open = false;
206
+ this.dispatchEvent(new CustomEvent("oh-close", { bubbles: true, composed: true }));
207
+ }
208
+ _handleBackdropClick() {
209
+ this._close();
210
+ }
211
+ /** Public method to open the drawer */
212
+ show() {
213
+ this.open = true;
214
+ }
215
+ /** Public method to close the drawer */
216
+ hide() {
217
+ this._close();
218
+ }
219
+ render() {
220
+ const drawerClasses = [
221
+ "drawer",
222
+ `drawer--${this.position}`,
223
+ this.open ? "is-open" : "",
224
+ ].filter(Boolean).join(" ");
225
+ const backdropClasses = [
226
+ "drawer-backdrop",
227
+ this.open ? "is-open" : "",
228
+ ].filter(Boolean).join(" ");
229
+ return html `
230
+ <div
231
+ class=${backdropClasses}
232
+ @click=${this._handleBackdropClick}
233
+ aria-hidden="true"
234
+ ></div>
235
+
236
+ <div
237
+ class=${drawerClasses}
238
+ role="dialog"
239
+ aria-modal="true"
240
+ aria-label=${this.heading || "Navigation menu"}
241
+ ?inert=${!this.open}
242
+ >
243
+ <div class="drawer__header">
244
+ ${this.heading
245
+ ? html `<h2 class="drawer__title">${this.heading}</h2>`
246
+ : html `<span></span>`}
247
+ <oh-button
248
+ variant="secondary"
249
+ size="sm"
250
+ icon-only
251
+ aria-label="Close menu"
252
+ @click=${this._close}
253
+ >
254
+ <oh-icon name="close"></oh-icon>
255
+ </oh-button>
256
+ </div>
257
+
258
+ <div class="drawer__content">
259
+ <slot></slot>
260
+ </div>
261
+ </div>
262
+ `;
263
+ }
264
+ };
265
+ __decorate([
266
+ property({ type: Boolean, reflect: true })
267
+ ], OhDrawer.prototype, "open", void 0);
268
+ __decorate([
269
+ property({ type: String })
270
+ ], OhDrawer.prototype, "position", void 0);
271
+ __decorate([
272
+ property({ type: String })
273
+ ], OhDrawer.prototype, "heading", void 0);
274
+ __decorate([
275
+ state()
276
+ ], OhDrawer.prototype, "_triggerElement", void 0);
277
+ __decorate([
278
+ query(".drawer")
279
+ ], OhDrawer.prototype, "_drawer", void 0);
280
+ OhDrawer = __decorate([
281
+ customElement("oh-drawer")
282
+ ], OhDrawer);
283
+ export { OhDrawer };
284
+ //# sourceMappingURL=oh-drawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-drawer.js","sourceRoot":"","sources":["../src/oh-drawer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * oh-footer
3
+ *
4
+ * A footer component with logo, multi-column links, and social icons.
5
+ *
6
+ * DESIGN DECISIONS:
7
+ * ─────────────────
8
+ * 1. LAYOUT
9
+ * - Multi-column grid layout
10
+ * - Logo and social on left
11
+ * - Link columns on right
12
+ *
13
+ * 2. STYLING
14
+ * - Accent blue background (dark)
15
+ * - White/inverse text and links
16
+ * - Generous padding
17
+ *
18
+ * @element oh-footer
19
+ *
20
+ * @slot logo - Slot for logo element
21
+ * @slot social - Slot for social media icons
22
+ * @slot - Default slot for link columns (use oh-stack for each column)
23
+ */
24
+ import { OhElement } from "./base.js";
25
+ import "./oh-container.js";
26
+ import "./oh-grid.js";
27
+ import "./oh-stack.js";
28
+ import "./oh-cluster.js";
29
+ export declare class OhFooter extends OhElement {
30
+ static styles: import("lit").CSSResult[];
31
+ /** Copyright text */
32
+ copyright: string;
33
+ render(): import("lit").TemplateResult<1>;
34
+ }
35
+ declare global {
36
+ interface HTMLElementTagNameMap {
37
+ "oh-footer": OhFooter;
38
+ }
39
+ }
40
+ //# sourceMappingURL=oh-footer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-footer.d.ts","sourceRoot":"","sources":["../src/oh-footer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,OAAO,mBAAmB,CAAC;AAC3B,OAAO,cAAc,CAAC;AACtB,OAAO,eAAe,CAAC;AACvB,OAAO,iBAAiB,CAAC;AAEzB,qBACa,QAAS,SAAQ,SAAS;IACrC,OAAgB,MAAM,4BAmCpB;IAEF,qBAAqB;IAErB,SAAS,SAAM;IAEf,MAAM;CAyBP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * oh-footer
3
+ *
4
+ * A footer component with logo, multi-column links, and social icons.
5
+ *
6
+ * DESIGN DECISIONS:
7
+ * ─────────────────
8
+ * 1. LAYOUT
9
+ * - Multi-column grid layout
10
+ * - Logo and social on left
11
+ * - Link columns on right
12
+ *
13
+ * 2. STYLING
14
+ * - Accent blue background (dark)
15
+ * - White/inverse text and links
16
+ * - Generous padding
17
+ *
18
+ * @element oh-footer
19
+ *
20
+ * @slot logo - Slot for logo element
21
+ * @slot social - Slot for social media icons
22
+ * @slot - Default slot for link columns (use oh-stack for each column)
23
+ */
24
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
25
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
26
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
27
+ 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;
28
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
29
+ };
30
+ import { html, css } from "lit";
31
+ import { customElement, property } from "lit/decorators.js";
32
+ import { OhElement, baseStyles } from "./base.js";
33
+ import "./oh-container.js";
34
+ import "./oh-grid.js";
35
+ import "./oh-stack.js";
36
+ import "./oh-cluster.js";
37
+ let OhFooter = class OhFooter extends OhElement {
38
+ constructor() {
39
+ super(...arguments);
40
+ /** Copyright text */
41
+ this.copyright = "";
42
+ }
43
+ static { this.styles = [
44
+ baseStyles,
45
+ css `
46
+ :host {
47
+ display: block;
48
+ background-color: var(--oh-color-accent-default);
49
+ color: var(--oh-color-text-on-accent);
50
+ font-family: var(--oh-font-family-sans);
51
+ font-size: var(--oh-font-size-base);
52
+ line-height: var(--oh-line-height-md);
53
+ padding: var(--oh-spacing-8) 0;
54
+ }
55
+
56
+ .footer__logo ::slotted(img) {
57
+ height: 32px;
58
+ width: auto;
59
+ }
60
+
61
+ .footer__copyright {
62
+ opacity: 0.8;
63
+ margin: 0;
64
+ }
65
+
66
+ /* Link columns */
67
+ ::slotted(oh-stack) {
68
+ min-width: 0;
69
+ }
70
+
71
+ /* Responsive - tablet: brand section spans full width */
72
+ @media (max-width: 900px) {
73
+ .footer__brand {
74
+ grid-column: 1 / -1;
75
+ }
76
+ }
77
+ `,
78
+ ]; }
79
+ render() {
80
+ return html `
81
+ <footer>
82
+ <oh-container size="lg">
83
+ <oh-grid columns="4" gap="xl">
84
+ <!-- Brand section -->
85
+ <oh-stack gap="md" class="footer__brand">
86
+ <div class="footer__logo">
87
+ <slot name="logo"></slot>
88
+ </div>
89
+ ${this.copyright
90
+ ? html `<p class="footer__copyright">${this.copyright}</p>`
91
+ : null}
92
+ <oh-cluster gap="lg">
93
+ <slot name="social"></slot>
94
+ </oh-cluster>
95
+ </oh-stack>
96
+
97
+ <!-- Link columns (each slotted oh-stack becomes a grid column) -->
98
+ <slot></slot>
99
+ </oh-grid>
100
+ </oh-container>
101
+ </footer>
102
+ `;
103
+ }
104
+ };
105
+ __decorate([
106
+ property({ type: String })
107
+ ], OhFooter.prototype, "copyright", void 0);
108
+ OhFooter = __decorate([
109
+ customElement("oh-footer")
110
+ ], OhFooter);
111
+ export { OhFooter };
112
+ //# sourceMappingURL=oh-footer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-footer.js","sourceRoot":"","sources":["../src/oh-footer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;;;;;AAEH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,mBAAmB,CAAC;AAC3B,OAAO,cAAc,CAAC;AACtB,OAAO,eAAe,CAAC;AACvB,OAAO,iBAAiB,CAAC;AAGlB,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,SAAS;IAAhC;;QAsCL,qBAAqB;QAErB,cAAS,GAAG,EAAE,CAAC;IA2BjB,CAAC;aAlEiB,WAAM,GAAG;QACvB,UAAU;QACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgCF;KACF,AAnCqB,CAmCpB;IAMF,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;;;;gBASC,IAAI,CAAC,SAAS;YACd,CAAC,CAAC,IAAI,CAAA,gCAAgC,IAAI,CAAC,SAAS,MAAM;YAC1D,CAAC,CAAC,IAAI;;;;;;;;;;;KAWjB,CAAC;IACJ,CAAC;;AA1BD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACZ;AAxCJ,QAAQ;IADpB,aAAa,CAAC,WAAW,CAAC;GACd,QAAQ,CAmEpB"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * oh-grid
3
+ *
4
+ * CSS Grid layout with configurable columns.
5
+ * Flexible grid system for cards, galleries, and layouts.
6
+ *
7
+ * DESIGN DECISIONS:
8
+ * ─────────────────
9
+ * 1. COLUMN PRESETS
10
+ * - 1-4 fixed columns
11
+ * - auto-fit: responsive columns with min-width
12
+ * - auto-fill: fills available space
13
+ *
14
+ * 2. MIN-WIDTH FOR AUTO COLUMNS
15
+ * - Configurable minimum column width
16
+ * - Defaults to 280px for card-friendly layouts
17
+ *
18
+ * 3. GAP SCALE
19
+ * - Uses design token spacing values
20
+ *
21
+ * @element oh-grid
22
+ */
23
+ import { OhElement } from "./base.js";
24
+ export type GridColumns = "1" | "2" | "3" | "4" | "auto-fit" | "auto-fill";
25
+ export type GridGap = "none" | "xs" | "sm" | "md" | "lg" | "xl";
26
+ export declare class OhGrid extends OhElement {
27
+ static styles: import("lit").CSSResult[];
28
+ columns: GridColumns;
29
+ gap: GridGap;
30
+ minWidth: string;
31
+ alignItems: "start" | "center" | "end" | "stretch";
32
+ updated(changedProperties: Map<string, unknown>): void;
33
+ render(): import("lit").TemplateResult<1>;
34
+ }
35
+ declare global {
36
+ interface HTMLElementTagNameMap {
37
+ "oh-grid": OhGrid;
38
+ }
39
+ }
40
+ //# sourceMappingURL=oh-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-grid.d.ts","sourceRoot":"","sources":["../src/oh-grid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,UAAU,GAAG,WAAW,CAAC;AAC3E,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhE,qBACa,MAAO,SAAQ,SAAS;IACnC,OAAgB,MAAM,4BA8FpB;IAGF,OAAO,EAAE,WAAW,CAAc;IAGlC,GAAG,EAAE,OAAO,CAAQ;IAGpB,QAAQ,SAAW;IAGnB,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAa;IAEtD,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAgBxD,MAAM;CAGP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * oh-grid
3
+ *
4
+ * CSS Grid layout with configurable columns.
5
+ * Flexible grid system for cards, galleries, and layouts.
6
+ *
7
+ * DESIGN DECISIONS:
8
+ * ─────────────────
9
+ * 1. COLUMN PRESETS
10
+ * - 1-4 fixed columns
11
+ * - auto-fit: responsive columns with min-width
12
+ * - auto-fill: fills available space
13
+ *
14
+ * 2. MIN-WIDTH FOR AUTO COLUMNS
15
+ * - Configurable minimum column width
16
+ * - Defaults to 280px for card-friendly layouts
17
+ *
18
+ * 3. GAP SCALE
19
+ * - Uses design token spacing values
20
+ *
21
+ * @element oh-grid
22
+ */
23
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
24
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
25
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
26
+ 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;
27
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
28
+ };
29
+ import { html, css } from "lit";
30
+ import { customElement, property } from "lit/decorators.js";
31
+ import { OhElement, baseStyles } from "./base.js";
32
+ let OhGrid = class OhGrid extends OhElement {
33
+ constructor() {
34
+ super(...arguments);
35
+ this.columns = "auto-fit";
36
+ this.gap = "md";
37
+ this.minWidth = "280px";
38
+ this.alignItems = "stretch";
39
+ }
40
+ static { this.styles = [
41
+ baseStyles,
42
+ css `
43
+ /* ═══════════════════════════════════════════════════════════════
44
+ ORANGE HALO GRID
45
+ CSS Grid layout • Responsive columns • Flexible gaps
46
+ ═══════════════════════════════════════════════════════════════ */
47
+
48
+ :host {
49
+ display: grid;
50
+ width: 100%;
51
+ }
52
+
53
+ /* Fixed column variants */
54
+ :host([columns="1"]) {
55
+ grid-template-columns: 1fr;
56
+ }
57
+
58
+ :host([columns="2"]) {
59
+ grid-template-columns: repeat(2, 1fr);
60
+ }
61
+
62
+ :host([columns="3"]) {
63
+ grid-template-columns: repeat(3, 1fr);
64
+ }
65
+
66
+ :host([columns="4"]) {
67
+ grid-template-columns: repeat(4, 1fr);
68
+ }
69
+
70
+ /* Gap variants */
71
+ :host([gap="none"]) {
72
+ gap: 0;
73
+ }
74
+
75
+ :host([gap="xs"]) {
76
+ gap: var(--oh-spacing-1);
77
+ }
78
+
79
+ :host([gap="sm"]) {
80
+ gap: var(--oh-spacing-2);
81
+ }
82
+
83
+ :host([gap="md"]) {
84
+ gap: var(--oh-spacing-4);
85
+ }
86
+
87
+ :host([gap="lg"]) {
88
+ gap: var(--oh-spacing-6);
89
+ }
90
+
91
+ :host([gap="xl"]) {
92
+ gap: var(--oh-spacing-8);
93
+ }
94
+
95
+ /* Alignment */
96
+ :host([align-items="start"]) {
97
+ align-items: start;
98
+ }
99
+
100
+ :host([align-items="center"]) {
101
+ align-items: center;
102
+ }
103
+
104
+ :host([align-items="end"]) {
105
+ align-items: end;
106
+ }
107
+
108
+ :host([align-items="stretch"]) {
109
+ align-items: stretch;
110
+ }
111
+
112
+ /* Responsive: stack on mobile for fixed columns */
113
+ @media (max-width: 640px) {
114
+ :host([columns="2"]),
115
+ :host([columns="3"]),
116
+ :host([columns="4"]) {
117
+ grid-template-columns: 1fr;
118
+ }
119
+ }
120
+
121
+ @media (min-width: 641px) and (max-width: 768px) {
122
+ :host([columns="3"]),
123
+ :host([columns="4"]) {
124
+ grid-template-columns: repeat(2, 1fr);
125
+ }
126
+ }
127
+
128
+ @media (min-width: 769px) and (max-width: 1024px) {
129
+ :host([columns="4"]) {
130
+ grid-template-columns: repeat(3, 1fr);
131
+ }
132
+ }
133
+ `,
134
+ ]; }
135
+ updated(changedProperties) {
136
+ super.updated(changedProperties);
137
+ // Handle auto-fit and auto-fill with dynamic min-width
138
+ if (changedProperties.has("columns") ||
139
+ changedProperties.has("minWidth")) {
140
+ if (this.columns === "auto-fit" || this.columns === "auto-fill") {
141
+ this.style.gridTemplateColumns = `repeat(${this.columns}, minmax(${this.minWidth}, 1fr))`;
142
+ }
143
+ else {
144
+ this.style.gridTemplateColumns = "";
145
+ }
146
+ }
147
+ }
148
+ render() {
149
+ return html `<slot></slot>`;
150
+ }
151
+ };
152
+ __decorate([
153
+ property({ type: String, reflect: true })
154
+ ], OhGrid.prototype, "columns", void 0);
155
+ __decorate([
156
+ property({ type: String, reflect: true })
157
+ ], OhGrid.prototype, "gap", void 0);
158
+ __decorate([
159
+ property({ type: String, attribute: "min-width" })
160
+ ], OhGrid.prototype, "minWidth", void 0);
161
+ __decorate([
162
+ property({ type: String, attribute: "align-items", reflect: true })
163
+ ], OhGrid.prototype, "alignItems", void 0);
164
+ OhGrid = __decorate([
165
+ customElement("oh-grid")
166
+ ], OhGrid);
167
+ export { OhGrid };
168
+ //# sourceMappingURL=oh-grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oh-grid.js","sourceRoot":"","sources":["../src/oh-grid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;;;;;AAEH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM3C,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,SAAS;IAA9B;;QAkGL,YAAO,GAAgB,UAAU,CAAC;QAGlC,QAAG,GAAY,IAAI,CAAC;QAGpB,aAAQ,GAAG,OAAO,CAAC;QAGnB,eAAU,GAA2C,SAAS,CAAC;IAqBjE,CAAC;aA/HiB,WAAM,GAAG;QACvB,UAAU;QACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2FF;KACF,AA9FqB,CA8FpB;IAcO,OAAO,CAAC,iBAAuC;QACtD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAEjC,uDAAuD;QACvD,IACE,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;YAChC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,EACjC,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;gBAChE,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,UAAU,IAAI,CAAC,OAAO,YAAY,IAAI,CAAC,QAAQ,SAAS,CAAC;YAC5F,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;;AA7BD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;uCACR;AAGlC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mCACtB;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;wCAChC;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;0CACL;AA3GpD,MAAM;IADlB,aAAa,CAAC,SAAS,CAAC;GACZ,MAAM,CAgIlB"}