@ulu/frontend 0.2.1 → 0.3.1

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 (41) hide show
  1. package/README.dev.md +16 -0
  2. package/dist/es/index.js +18 -16
  3. package/dist/es/ui/dialog.d.ts +3 -1
  4. package/dist/es/ui/dialog.d.ts.map +1 -1
  5. package/dist/es/ui/dialog.js +57 -51
  6. package/dist/es/ui/modal-builder.d.ts +6 -0
  7. package/dist/es/ui/modal-builder.d.ts.map +1 -1
  8. package/dist/es/ui/modal-builder.js +53 -45
  9. package/dist/es/utils/dialog.d.ts +14 -0
  10. package/dist/es/utils/dialog.d.ts.map +1 -0
  11. package/dist/es/utils/dialog.js +16 -0
  12. package/dist/es/utils/iframe.d.ts +15 -0
  13. package/dist/es/utils/iframe.d.ts.map +1 -0
  14. package/dist/es/utils/iframe.js +33 -0
  15. package/dist/es/utils/index.d.ts +1 -0
  16. package/dist/umd/frontend.css +1 -1
  17. package/dist/umd/ulu-frontend.umd.js +12 -12
  18. package/lib/js/exports.md +1 -0
  19. package/lib/js/ui/dialog.js +23 -3
  20. package/lib/js/ui/modal-builder.js +21 -0
  21. package/lib/js/utils/dialog.js +29 -0
  22. package/lib/js/utils/iframe.js +59 -0
  23. package/lib/js/utils/index.js +4 -1
  24. package/lib/scss/_color.scss +1 -1
  25. package/lib/scss/_element.scss +15 -0
  26. package/lib/scss/_utils.scss +22 -0
  27. package/lib/scss/base/_elements.scss +3 -0
  28. package/lib/scss/components/_accordion.scss +7 -2
  29. package/lib/scss/components/_badge.scss +1 -1
  30. package/lib/scss/components/_button-group.scss +8 -3
  31. package/lib/scss/components/_card-grid.scss +8 -14
  32. package/lib/scss/components/_card.scss +15 -13
  33. package/lib/scss/components/_data-list.scss +270 -0
  34. package/lib/scss/components/_data-table.scss +3 -1
  35. package/lib/scss/components/_index.scss +12 -0
  36. package/lib/scss/components/_menu-stack.scss +1 -1
  37. package/lib/scss/components/_modal.scss +97 -19
  38. package/lib/scss/components/_ratio-box.scss +11 -10
  39. package/lib/scss/components/_table-scroller.scss +63 -0
  40. package/lib/scss/helpers/_utilities.scss +23 -1
  41. package/package.json +4 -1
@@ -4,6 +4,7 @@
4
4
 
5
5
  @use "sass:map";
6
6
  @use "sass:meta";
7
+ @use "sass:list";
7
8
 
8
9
  @use "../color";
9
10
  @use "../element";
@@ -11,9 +12,14 @@
11
12
  @use "../typography";
12
13
  @use "../selector";
13
14
  @use "../utils";
15
+ @use "../breakpoint";
14
16
 
15
17
  // Used for function fallback
16
18
  $-fallbacks: (
19
+ "breakpoint" : (
20
+ "function" : meta.get-function("get", false, "breakpoint"),
21
+ "property" : "default"
22
+ ),
17
23
  "backdrop-color" : (
18
24
  "function" : meta.get-function("get", false, "element"),
19
25
  "property" : "backdrop-color"
@@ -43,6 +49,7 @@ $-fallbacks: (
43
49
  /// @prop {Dimension} height [340px] The min-height of the modal.
44
50
  /// @prop {Dimension} height-no-header [100px] The min-height of the modal.
45
51
  /// @prop {Dimension} width [60rem] The width of the Modal
52
+ /// @prop {Dimension} min-width [300px] The min-width of the Modal (for resizing, etc)
46
53
  /// @prop {Time} animation-duration [300ms] Animation duration for the modal opening.
47
54
  /// @prop {Time} animation-duration-exit [150ms] Animation duration for the modal closing.
48
55
  /// @prop {CssValue} animation-timing-function [cubic-bezier(0, 0, .2, 1)] The animation timing menu of the modal.
@@ -75,6 +82,9 @@ $-fallbacks: (
75
82
  /// @prop {String} title-size [large] The font-size of the title. This uses typography.scss, so the value of this options should be a variable from typography.scss.
76
83
  /// @prop {CssValue} title-text-transform [null] Transform option for the title.
77
84
  /// @prop {Map} sizes [Map] Size options to enable unique stylings.
85
+ /// @prop {String} breakpoint [true] Optional breakpoint for modals (used for adaptive things like fullscreen-mobile), if set to true will fallback to breakpoint default
86
+ /// @prop {String} frame-aspect-ratio [list.slash(16, 9)] Default aspect ratio for single embedded items in frame-ratio layout
87
+ /// @prop {String} frame-fill-min-height [65vh] Default minimum height for single embedded items in frame-fill layout
78
88
 
79
89
  $config: (
80
90
  "backdrop-color" : true,
@@ -86,6 +96,7 @@ $config: (
86
96
  "height": 340px,
87
97
  "height-no-header": 100px,
88
98
  "width": 60rem,
99
+ "min-width": 300px,
89
100
  "width-left-right" : 30rem,
90
101
  "animation-duration" : 300ms,
91
102
  "animation-duration-exit" : 150ms,
@@ -119,6 +130,9 @@ $config: (
119
130
  "title-icon-margin" : 0.5em,
120
131
  "title-size" : "large",
121
132
  "title-text-transform" : null,
133
+ "breakpoint" : true,
134
+ "frame-aspect-ratio" : list.slash(16, 9),
135
+ "frame-fill-min-height" : 65vh,
122
136
  "sizes" : (
123
137
  "small" : 30rem,
124
138
  "large" : 80rem
@@ -150,6 +164,7 @@ $config: (
150
164
 
151
165
  @mixin styles {
152
166
  $prefix: selector.class("modal");
167
+ $breakpoint: get("breakpoint");
153
168
 
154
169
  // // Before it's moved
155
170
  [data-ulu-modal-builder] {
@@ -171,9 +186,10 @@ $config: (
171
186
  padding: 0;
172
187
  border: 0;
173
188
  width: get("width");
174
- min-width: 200px; // For resizing minimum width
189
+ min-width: get("min-width"); // For resizing minimum width
175
190
  min-height: get("height");
176
191
  max-height: 100vh;
192
+ max-height: 100dvh;
177
193
  max-width: 100%;
178
194
  overflow-y: hidden;
179
195
  box-sizing: border-box;
@@ -196,19 +212,20 @@ $config: (
196
212
  display: flex;
197
213
  justify-content: space-between;
198
214
  align-items: center;
199
- flex: 0;
215
+ flex: 0 0 auto;
200
216
  padding: get("header-padding");
201
217
  border-bottom: get("header-border-bottom");
202
218
  background-color: color.get(get("header-background-color"));
203
219
  color: color.get(get("header-color"));
204
220
  }
205
221
  #{ $prefix }__body {
206
- flex: 1;
222
+ flex: 1 1 auto;
223
+ min-height: 0; // to ensure the flex grow container can get smaller than it's content (and scroll) when needed
207
224
  overflow: auto;
208
225
  padding: get("body-padding");
209
226
  }
210
227
  #{ $prefix }__footer {
211
- flex: 0;
228
+ flex: 0 0 auto;
212
229
  padding: get("footer-padding");
213
230
  background-color: color.get(get("footer-background-color"));
214
231
  border-top: get("footer-border-top");
@@ -245,10 +262,6 @@ $config: (
245
262
  }
246
263
  }
247
264
 
248
- #{ $prefix }__close-icon {
249
- // transform: translatey(get("close-icon-vertical-offset"));
250
- }
251
-
252
265
  #{ $prefix }__resizer {
253
266
  position: absolute;
254
267
  overflow: hidden;
@@ -293,15 +306,17 @@ $config: (
293
306
  }
294
307
  }
295
308
 
296
- #{ $prefix }--fullscreen {
297
- width: 100%;
298
- height: 100%;
299
- border-radius: 0;
309
+ // Fullscreen and left and right defaults (width overridden below)
310
+ #{ $prefix }--fullscreen,
311
+ #{ $prefix }--right,
312
+ #{ $prefix }--left {
313
+ @include -fullscreen-common-properties();
300
314
  }
315
+ // Left/Right specific
316
+ // - Note these properties are all important even though they seem redundant
317
+ // they are tested and solve quirks with dialog positioning/animation
301
318
  #{ $prefix }--right,
302
319
  #{ $prefix }--left {
303
- border-radius: 0;
304
- height: 100vh;
305
320
  width: get("width-left-right");
306
321
  top: 0;
307
322
  bottom: 0;
@@ -358,11 +373,11 @@ $config: (
358
373
  &#{ $prefix }--left {
359
374
  padding-right: get("resizer-width");
360
375
  }
361
- // &#{ $prefix }--center {
362
- // resize: both;
363
- // }
364
376
  }
365
- #{ $prefix }--body-fills {
377
+ // Share body flush layout
378
+ #{ $prefix }--body-fills,
379
+ #{ $prefix }--frame-ratio,
380
+ #{ $prefix }--frame-fill {
366
381
  #{ $prefix }__header {
367
382
  border-bottom: none;
368
383
  }
@@ -370,10 +385,65 @@ $config: (
370
385
  padding: 0;
371
386
  }
372
387
  }
373
-
374
388
  #{ $prefix }--no-min-height {
375
389
  min-height: 0;
376
390
  }
391
+
392
+ // Frame layouts for absolute positioned single content (e.g. iframes)
393
+ // Both modes use absolute positioning to escape wrappers (p, div, etc)
394
+ #{ $prefix }--frame-ratio,
395
+ #{ $prefix }--frame-fill {
396
+ #{ $prefix }__body {
397
+ position: relative;
398
+ }
399
+ #{ $prefix }__frame-content {
400
+ position: absolute;
401
+ top: 0;
402
+ left: 0;
403
+ width: 100%;
404
+ height: 100%;
405
+ border: none;
406
+ }
407
+ }
408
+
409
+ // Ratio-specific: disable minimum heights and flex-grow so it perfectly wraps
410
+ #{ $prefix }--frame-ratio {
411
+ min-height: 0;
412
+ #{ $prefix }__body {
413
+ flex: none;
414
+ // Default, can be overridden inline
415
+ aspect-ratio: utils.normalize-aspect-ratio(get("frame-aspect-ratio"));
416
+ }
417
+ }
418
+
419
+ // Fill-specific: default height
420
+ #{ $prefix }--frame-fill {
421
+ #{ $prefix }__body {
422
+ // Default, can be overridden inline
423
+ min-height: get("frame-fill-min-height");
424
+ }
425
+ }
426
+
427
+ @if breakpoint.exists($breakpoint) {
428
+ #{ $prefix }--fullscreen-mobile {
429
+ @include breakpoint.max($breakpoint) {
430
+ @include -fullscreen-common-properties();
431
+ top: 50%;
432
+ left: 50%;
433
+ bottom: auto;
434
+ right: auto;
435
+ transform: translate(-50%, -50%);
436
+ animation: uluModalCenterOut get("animation-duration-exit") get("animation-timing-function");
437
+ &[open] {
438
+ animation: uluModalCenterIn get("animation-duration") get("animation-timing-function");
439
+ }
440
+ #{ $prefix }__resizer {
441
+ display: none;
442
+ }
443
+ }
444
+ }
445
+ }
446
+
377
447
  // Will display as content when printing
378
448
  // NOTE: This will not work with native dialog
379
449
  // Printing works with modal printer by cloning mechanism
@@ -522,3 +592,11 @@ $config: (
522
592
  }
523
593
  }
524
594
 
595
+
596
+ // Internal mixin to make sure this repeated CSS is identical for compression
597
+ @mixin -fullscreen-common-properties() {
598
+ width: 100%;
599
+ height: 100%;
600
+ height: 100dvh;
601
+ border-radius: 0;
602
+ }
@@ -1,23 +1,26 @@
1
1
  ////
2
2
  /// @group ratio-box
3
3
  ////
4
- /// Uses padding trick to keep ratio. Defaults to 4:3 (standard). Used for responsive iframe or images (object-fit), etc
4
+ /// Uses aspect-ratio to keep ratio. Defaults to 4/3 (standard). Used for responsive iframe or images (object-fit), etc.
5
5
 
6
6
  @use "sass:map";
7
+ @use "sass:math";
8
+ @use "sass:meta";
9
+ @use "sass:list";
7
10
  @use "../utils";
8
11
  @use "../layout";
9
12
 
10
13
  /// Module Settings
11
14
  /// @type Map
12
- /// @prop {Number} size [75%] Default height ratio (of width 100%)
15
+ /// @prop {String|Number} size ["4/3"] Default aspect ratio (can be string like "16/9" or legacy percentage value)
13
16
  /// @prop {Map} sizes [Map] Other ratios to add (apply with modifier class)
14
17
 
15
18
  $config: (
16
- "size" : 75%,
19
+ "size" : list.slash(4, 3),
17
20
  "sizes" : (
18
- "16x9" : 56.25%,
19
- "9x16" : 177.77%,
20
- "3x4" : 133.33%
21
+ "16x9" : list.slash(16, 9),
22
+ "9x16" : list.slash(9, 16),
23
+ "3x4" : list.slash(3, 4)
21
24
  )
22
25
  ) !default;
23
26
 
@@ -46,16 +49,14 @@ $config: (
46
49
  @mixin styles {
47
50
  .ratio-box {
48
51
  position: relative;
49
- overflow: hidden;
50
- padding: get("size") 0 0 0;
52
+ aspect-ratio: utils.normalize-aspect-ratio(get("size"));
51
53
  }
52
54
  .ratio-box__content {
53
55
  @include layout.absolute-fill(true);
54
- border: 0;
55
56
  }
56
57
  @each $name, $size in get("sizes") {
57
58
  .ratio-box--#{ $name } {
58
- padding-top: $size;
59
+ aspect-ratio: utils.normalize-aspect-ratio($size);
59
60
  }
60
61
  }
61
62
  }
@@ -0,0 +1,63 @@
1
+ ////
2
+ /// @group table-scroller
3
+ /// Simple wrapper for tables to make them overflow-x, not to be confused with
4
+ /// sticky table plugin, this is for simple html tables
5
+ /// - Note in situations where you can't use a wrapper you can sometimes get by with display block / max-content hack
6
+ ////
7
+
8
+ @use "sass:map";
9
+ @use "sass:math";
10
+
11
+ @use "../selector";
12
+ @use "../utils";
13
+
14
+ /// Module Settings
15
+ /// @type Map
16
+ /// @prop {List|Number} margin [(1em, 0)] Optional margin for this component
17
+
18
+ $config: (
19
+ "margin" : (1em, 0),
20
+ // "example": "background",
21
+ ) !default;
22
+
23
+ /// Change modules $config
24
+ /// @param {Map} $changes Map of changes
25
+ /// @example scss
26
+ /// @include ulu.component-table-scroller-set(( "property" : value ));
27
+
28
+ @mixin set($changes) {
29
+ $config: map.merge($config, $changes) !global;
30
+ }
31
+
32
+ /// Get a config option
33
+ /// @param {Map} $name Name of property
34
+ /// @example scss
35
+ /// @include ulu.component-table-scroller-get("property");
36
+
37
+ @function get($name) {
38
+ @return utils.require-map-get($config, $name, "table-scroller [config]");
39
+ }
40
+
41
+ /// Prints component styles
42
+ /// @demo table-scroller
43
+ /// @example scss
44
+ /// @include ulu.component-table-scroller-styles();
45
+
46
+ @mixin styles {
47
+ $prefix: selector.class("table-scroller");
48
+
49
+ #{ $prefix } {
50
+ width: 100%;
51
+ overflow-x: auto;
52
+ margin: get("margin");
53
+ > table {
54
+ min-width: 100%;
55
+ max-width: none;
56
+ }
57
+ }
58
+ #{ $prefix }--nowrap {
59
+ > table > thead th {
60
+ white-space: nowrap;
61
+ }
62
+ }
63
+ }
@@ -23,7 +23,8 @@
23
23
  $prefix-crop-margins: selector.class("crop-margins");
24
24
  $prefix-no-padding: selector.class("no-padding");
25
25
  $prefix-align-self: selector.class("align-self");
26
-
26
+ $prefix-align-items: selector.class("align-items");
27
+ $prefix-justify-content: selector.class("justify-content");
27
28
 
28
29
  @include utils.file-header('helpers', 'utilities');
29
30
 
@@ -129,6 +130,27 @@
129
130
  #{ $prefix-align-self }-baseline {
130
131
  align-self: baseline;
131
132
  }
133
+ #{ $prefix-align-items }-start {
134
+ align-items: flex-start;
135
+ }
136
+ #{ $prefix-align-items }-center {
137
+ align-items: center;
138
+ }
139
+ #{ $prefix-align-items }-end {
140
+ align-items: flex-end;
141
+ }
142
+ #{ $prefix-justify-content }-start {
143
+ justify-content: flex-start;
144
+ }
145
+ #{ $prefix-justify-content }-center {
146
+ justify-content: center;
147
+ }
148
+ #{ $prefix-justify-content }-end {
149
+ justify-content: flex-end;
150
+ }
151
+ #{ $prefix-justify-content }-space-between {
152
+ justify-content: space-between;
153
+ }
132
154
  #{ selector.class("overflow-hidden") } {
133
155
  overflow: hidden;
134
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ulu/frontend",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "A framework-agnostic frontend toolkit providing a modular, tree-shakable library of accessible components and utilities. Designed for seamless integration, it features a highly configurable SCSS system for any environment and vanilla JavaScript modules optimized for traditional websites and content management systems.",
5
5
  "type": "module",
6
6
  "files": [
@@ -34,6 +34,8 @@
34
34
  "build:es": "BUILD_FORMAT=es vite build",
35
35
  "build:umd": "BUILD_FORMAT=umd vite build",
36
36
  "dev": "vite --config site/vite.config.js",
37
+ "dev:inspect": "node --inspect-brk node_modules/.bin/vite --config site/vite.config.js",
38
+ "dev:host": "vite --config site/vite.config.js --host",
37
39
  "dev:nogen": "NO_DOC_GEN=true vite --config site/vite.config.js",
38
40
  "docs:build": "vite build --config site/vite.config.js",
39
41
  "deploy": "npm run build && npm run docs:build"
@@ -101,6 +103,7 @@
101
103
  "eleventy-plugin-nesting-toc": "^1.3.0",
102
104
  "fs-extra": "^11.2.0",
103
105
  "instantsearch.js": "^4.68.1",
106
+ "js-beautify": "^1.15.4",
104
107
  "jsdoc": "^4.0.2",
105
108
  "jsdoc-to-markdown": "^9.1.3",
106
109
  "markdown-it-anchor": "^8.6.7",