luxen-ui 0.6.1 → 0.6.2

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.
@@ -48,11 +48,6 @@
48
48
  --background-color: transparent;
49
49
  --background-color-hover: light-dark(var(--l-color-gray-100), var(--l-color-gray-700));
50
50
 
51
- /*
52
- Accessibility: the overall size should be at least 44 pixels in height and width
53
- https://www.benjystanton.co.uk/blog/accessible-close-buttons/
54
- */
55
- padding: var(--l-spacing-2);
56
51
  border-radius: var(--l-radius-sm);
57
52
  background-color: var(--background-color);
58
53
 
@@ -48,11 +48,6 @@
48
48
  --background-color: transparent;
49
49
  --background-color-hover: light-dark(var(--l-color-gray-100), var(--l-color-gray-700));
50
50
 
51
- /*
52
- Accessibility: the overall size should be at least 44 pixels in height and width
53
- https://www.benjystanton.co.uk/blog/accessible-close-buttons/
54
- */
55
- padding: var(--l-spacing-2);
56
51
  border-radius: var(--l-radius-sm);
57
52
  background-color: var(--background-color);
58
53
 
@@ -2322,6 +2322,14 @@
2322
2322
  "description": "Hide the header entirely (title and close slot).",
2323
2323
  "default": "false"
2324
2324
  },
2325
+ {
2326
+ "kind": "field",
2327
+ "name": "_modalKind",
2328
+ "type": {
2329
+ "text": "string"
2330
+ },
2331
+ "default": "'centered'"
2332
+ },
2325
2333
  {
2326
2334
  "kind": "field",
2327
2335
  "name": "_mouseDownTarget",
@@ -2547,7 +2555,7 @@
2547
2555
  "name": "--size"
2548
2556
  },
2549
2557
  {
2550
- "description": "Drawer border radius on the inner edges. Default `0.75rem`.",
2558
+ "description": "Drawer border radius on the inner edges. Default `0.375rem`.",
2551
2559
  "name": "--border-radius",
2552
2560
  "inheritedFrom": {
2553
2561
  "name": "Dialog",
@@ -2679,99 +2687,20 @@
2679
2687
  }
2680
2688
  }
2681
2689
  ],
2682
- "events": [
2683
- {
2684
- "description": "Fired when the drawer opens. Not cancelable.",
2685
- "name": "show",
2686
- "inheritedFrom": {
2687
- "name": "Dialog",
2688
- "module": "src/html/elements/dialog/dialog.ts"
2689
- }
2690
- },
2691
- {
2692
- "description": "Fired after the open animation completes.",
2693
- "name": "after-show",
2694
- "inheritedFrom": {
2695
- "name": "Dialog",
2696
- "module": "src/html/elements/dialog/dialog.ts"
2697
- }
2698
- },
2699
- {
2700
- "description": "Fired when the drawer is about to close. Cancelable — call `event.preventDefault()` to keep it open.",
2701
- "name": "hide",
2702
- "inheritedFrom": {
2703
- "name": "Dialog",
2704
- "module": "src/html/elements/dialog/dialog.ts"
2705
- }
2706
- },
2707
- {
2708
- "description": "Fired after the close animation completes.",
2709
- "name": "after-hide",
2710
- "inheritedFrom": {
2711
- "name": "Dialog",
2712
- "module": "src/html/elements/dialog/dialog.ts"
2713
- }
2714
- }
2715
- ],
2716
- "superclass": {
2717
- "name": "Dialog",
2718
- "module": "/dist/elements/dialog/dialog.js"
2719
- },
2720
- "attributes": [
2721
- {
2722
- "name": "title",
2723
- "type": {
2724
- "text": "string"
2725
- },
2726
- "default": "''",
2727
- "description": "Dialog title rendered in the header.",
2728
- "fieldName": "title",
2729
- "inheritedFrom": {
2730
- "name": "Dialog",
2731
- "module": "src/html/elements/dialog/dialog.ts"
2732
- }
2733
- },
2734
- {
2735
- "name": "open",
2736
- "type": {
2737
- "text": "boolean"
2738
- },
2739
- "default": "false",
2740
- "description": "Whether the dialog is open.",
2741
- "fieldName": "open",
2742
- "inheritedFrom": {
2743
- "name": "Dialog",
2744
- "module": "src/html/elements/dialog/dialog.ts"
2745
- }
2746
- },
2690
+ "members": [
2747
2691
  {
2748
- "name": "light-dismiss",
2692
+ "kind": "field",
2693
+ "name": "_modalKind",
2749
2694
  "type": {
2750
- "text": "boolean"
2695
+ "text": "'centered' | 'edge'"
2751
2696
  },
2752
- "default": "false",
2753
- "description": "Close when the backdrop is clicked.",
2754
- "fieldName": "lightDismiss",
2697
+ "privacy": "protected",
2698
+ "default": "'edge'",
2755
2699
  "inheritedFrom": {
2756
2700
  "name": "Dialog",
2757
2701
  "module": "src/html/elements/dialog/dialog.ts"
2758
2702
  }
2759
2703
  },
2760
- {
2761
- "name": "without-header",
2762
- "type": {
2763
- "text": "boolean"
2764
- },
2765
- "default": "false",
2766
- "description": "Hide the header entirely (title and close slot).",
2767
- "fieldName": "withoutHeader",
2768
- "inheritedFrom": {
2769
- "name": "Dialog",
2770
- "module": "src/html/elements/dialog/dialog.ts"
2771
- }
2772
- }
2773
- ],
2774
- "members": [
2775
2704
  {
2776
2705
  "kind": "field",
2777
2706
  "name": "title",
@@ -3006,6 +2935,98 @@
3006
2935
  "module": "src/html/shared/luxen-element.ts"
3007
2936
  }
3008
2937
  }
2938
+ ],
2939
+ "events": [
2940
+ {
2941
+ "description": "Fired when the drawer opens. Not cancelable.",
2942
+ "name": "show",
2943
+ "inheritedFrom": {
2944
+ "name": "Dialog",
2945
+ "module": "src/html/elements/dialog/dialog.ts"
2946
+ }
2947
+ },
2948
+ {
2949
+ "description": "Fired after the open animation completes.",
2950
+ "name": "after-show",
2951
+ "inheritedFrom": {
2952
+ "name": "Dialog",
2953
+ "module": "src/html/elements/dialog/dialog.ts"
2954
+ }
2955
+ },
2956
+ {
2957
+ "description": "Fired when the drawer is about to close. Cancelable — call `event.preventDefault()` to keep it open.",
2958
+ "name": "hide",
2959
+ "inheritedFrom": {
2960
+ "name": "Dialog",
2961
+ "module": "src/html/elements/dialog/dialog.ts"
2962
+ }
2963
+ },
2964
+ {
2965
+ "description": "Fired after the close animation completes.",
2966
+ "name": "after-hide",
2967
+ "inheritedFrom": {
2968
+ "name": "Dialog",
2969
+ "module": "src/html/elements/dialog/dialog.ts"
2970
+ }
2971
+ }
2972
+ ],
2973
+ "superclass": {
2974
+ "name": "Dialog",
2975
+ "module": "/dist/elements/dialog/dialog.js"
2976
+ },
2977
+ "attributes": [
2978
+ {
2979
+ "name": "title",
2980
+ "type": {
2981
+ "text": "string"
2982
+ },
2983
+ "default": "''",
2984
+ "description": "Dialog title rendered in the header.",
2985
+ "fieldName": "title",
2986
+ "inheritedFrom": {
2987
+ "name": "Dialog",
2988
+ "module": "src/html/elements/dialog/dialog.ts"
2989
+ }
2990
+ },
2991
+ {
2992
+ "name": "open",
2993
+ "type": {
2994
+ "text": "boolean"
2995
+ },
2996
+ "default": "false",
2997
+ "description": "Whether the dialog is open.",
2998
+ "fieldName": "open",
2999
+ "inheritedFrom": {
3000
+ "name": "Dialog",
3001
+ "module": "src/html/elements/dialog/dialog.ts"
3002
+ }
3003
+ },
3004
+ {
3005
+ "name": "light-dismiss",
3006
+ "type": {
3007
+ "text": "boolean"
3008
+ },
3009
+ "default": "false",
3010
+ "description": "Close when the backdrop is clicked.",
3011
+ "fieldName": "lightDismiss",
3012
+ "inheritedFrom": {
3013
+ "name": "Dialog",
3014
+ "module": "src/html/elements/dialog/dialog.ts"
3015
+ }
3016
+ },
3017
+ {
3018
+ "name": "without-header",
3019
+ "type": {
3020
+ "text": "boolean"
3021
+ },
3022
+ "default": "false",
3023
+ "description": "Hide the header entirely (title and close slot).",
3024
+ "fieldName": "withoutHeader",
3025
+ "inheritedFrom": {
3026
+ "name": "Dialog",
3027
+ "module": "src/html/elements/dialog/dialog.ts"
3028
+ }
3029
+ }
3009
3030
  ]
3010
3031
  }
3011
3032
  ],
@@ -8049,7 +8070,7 @@
8049
8070
  {
8050
8071
  "kind": "variable",
8051
8072
  "name": "u",
8052
- "default": "class extends n{constructor(...e){super(...e),this.title=``,this.open=!1,this.lightDismiss=!1,this.withoutHeader=!1,this._mouseDownTarget=null,this._commandListener={handleEvent:e=>this._onCommand(e)}}static{this.styles=[o,s]}connectedCallback(){super.connectedCallback(),this.addEventListener(`command`,this._commandListener)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`command`,this._commandListener)}firstUpdated(){this.dialog.addEventListener(`cancel`,e=>this._onCancel(e)),this.dialog.addEventListener(`close`,()=>this._onNativeClose()),this.dialog.addEventListener(`mousedown`,e=>{this._mouseDownTarget=e.target}),this.dialog.addEventListener(`click`,e=>this._onDialogClick(e))}updated(e){if(e.has(`open`)){if(this.open&&!this.dialog.open)this.emit(`show`),this.toggleAttribute(`data-modal`,!0),this.dialog.showModal(),this._focusAutofocusTarget(),this._emitAfter(`after-show`);else if(!this.open&&this.dialog.open){if(!this.emit(`hide`,{cancelable:!0})){this.open=!0;return}this.dialog.close()}}}_onCommand(e){switch(e.command){case`--hide`:this.open=!1;break;case`--show`:this.open=!0;break}}_onCancel(e){this.emit(`hide`,{cancelable:!0})||e.preventDefault()}_onNativeClose(){this.open=!1,this.removeAttribute(`data-modal`),this._emitAfter(`after-hide`)}_onDialogClick(e){let t=e.target===this.dialog&&this._mouseDownTarget===this.dialog;if(this._mouseDownTarget=null,t){if(this.lightDismiss){c||(this.open=!1);return}this._nudgeDismiss()}}_nudgeDismiss(){matchMedia(`(prefers-reduced-motion: reduce)`).matches||(this._nudgeAnimation?.cancel(),this._nudgeAnimation=this.dialog.animate([{transform:`scale(1)`},{transform:`scale(1.02)`},{transform:`scale(1)`}],{duration:250,easing:`ease-in-out`}))}async _emitAfter(e){await new Promise(e=>requestAnimationFrame(()=>e(null)));let t=this.dialog.getAnimations({subtree:!1});await Promise.all(t.map(e=>e.finished.catch(()=>{}))),e===`after-show`===this.open&&this.emit(e)}_focusAutofocusTarget(){this.querySelector(`[autofocus]`)?.focus({preventScroll:!0})}render(){return e` <dialog part=\"dialog\" closedby=${this.lightDismiss&&c?`any`:t} > ${this.withoutHeader?t:e` <header part=\"header\"> <slot name=\"title\"> ${this.title?e`<h2 part=\"title\">${this.title}</h2>`:t} </slot> <slot name=\"close\"></slot> </header> `} <div part=\"body\"> <slot></slot> </div> <footer part=\"footer\"> <slot name=\"footer\"></slot> </footer> </dialog> `}}"
8073
+ "default": "class extends n{constructor(...e){super(...e),this.title=``,this.open=!1,this.lightDismiss=!1,this.withoutHeader=!1,this._modalKind=`centered`,this._mouseDownTarget=null,this._commandListener={handleEvent:e=>this._onCommand(e)}}static{this.styles=[o,s]}connectedCallback(){super.connectedCallback(),this.addEventListener(`command`,this._commandListener)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`command`,this._commandListener)}firstUpdated(){this.dialog.addEventListener(`cancel`,e=>this._onCancel(e)),this.dialog.addEventListener(`close`,()=>this._onNativeClose()),this.dialog.addEventListener(`mousedown`,e=>{this._mouseDownTarget=e.target}),this.dialog.addEventListener(`click`,e=>this._onDialogClick(e))}updated(e){if(e.has(`open`)){if(this.open&&!this.dialog.open)this.emit(`show`),this.setAttribute(`data-modal`,this._modalKind),this.dialog.showModal(),this._focusAutofocusTarget(),this._emitAfter(`after-show`);else if(!this.open&&this.dialog.open){if(!this.emit(`hide`,{cancelable:!0})){this.open=!0;return}this.dialog.close()}}}_onCommand(e){switch(e.command){case`--hide`:this.open=!1;break;case`--show`:this.open=!0;break}}_onCancel(e){this.emit(`hide`,{cancelable:!0})||e.preventDefault()}_onNativeClose(){this.open=!1,this.removeAttribute(`data-modal`),this._emitAfter(`after-hide`)}_onDialogClick(e){let t=e.target===this.dialog&&this._mouseDownTarget===this.dialog;if(this._mouseDownTarget=null,t){if(this.lightDismiss){c||(this.open=!1);return}this._nudgeDismiss()}}_nudgeDismiss(){matchMedia(`(prefers-reduced-motion: reduce)`).matches||(this._nudgeAnimation?.cancel(),this._nudgeAnimation=this.dialog.animate([{transform:`scale(1)`},{transform:`scale(1.02)`},{transform:`scale(1)`}],{duration:250,easing:`ease-in-out`}))}async _emitAfter(e){await new Promise(e=>requestAnimationFrame(()=>e(null)));let t=this.dialog.getAnimations({subtree:!1});await Promise.all(t.map(e=>e.finished.catch(()=>{}))),e===`after-show`===this.open&&this.emit(e)}_focusAutofocusTarget(){this.querySelector(`[autofocus]`)?.focus({preventScroll:!0})}render(){return e` <dialog part=\"dialog\" closedby=${this.lightDismiss&&c?`any`:t} > ${this.withoutHeader?t:e` <header part=\"header\"> <slot name=\"title\"> ${this.title?e`<h2 part=\"title\">${this.title}</h2>`:t} </slot> <slot name=\"close\"></slot> </header> `} <div part=\"body\"> <slot></slot> </div> <footer part=\"footer\"> <slot name=\"footer\"></slot> </footer> </dialog> `}}"
8053
8074
  }
8054
8075
  ],
8055
8076
  "exports": [
@@ -8123,7 +8144,7 @@
8123
8144
  {
8124
8145
  "kind": "variable",
8125
8146
  "name": "s",
8126
- "default": "class extends a{static{this.styles=[r,i,o]}}"
8147
+ "default": "class extends a{constructor(...e){super(...e),this._modalKind=`edge`}static{this.styles=[r,i,o]}}"
8127
8148
  }
8128
8149
  ],
8129
8150
  "exports": [
@@ -10390,6 +10411,15 @@
10390
10411
  "text": "HTMLDialogElement"
10391
10412
  }
10392
10413
  },
10414
+ {
10415
+ "kind": "field",
10416
+ "name": "_modalKind",
10417
+ "type": {
10418
+ "text": "'centered' | 'edge'"
10419
+ },
10420
+ "privacy": "protected",
10421
+ "default": "'centered'"
10422
+ },
10393
10423
  {
10394
10424
  "kind": "field",
10395
10425
  "name": "_mouseDownTarget",
@@ -10747,7 +10777,7 @@
10747
10777
  "name": "--size"
10748
10778
  },
10749
10779
  {
10750
- "description": "Drawer border radius on the inner edges. Default `0.75rem`.",
10780
+ "description": "Drawer border radius on the inner edges. Default `0.375rem`.",
10751
10781
  "name": "--border-radius",
10752
10782
  "inheritedFrom": {
10753
10783
  "name": "Dialog",
@@ -10880,6 +10910,19 @@
10880
10910
  }
10881
10911
  ],
10882
10912
  "members": [
10913
+ {
10914
+ "kind": "field",
10915
+ "name": "_modalKind",
10916
+ "type": {
10917
+ "text": "'centered' | 'edge'"
10918
+ },
10919
+ "privacy": "protected",
10920
+ "default": "'edge'",
10921
+ "inheritedFrom": {
10922
+ "name": "Dialog",
10923
+ "module": "src/html/elements/dialog/dialog.ts"
10924
+ }
10925
+ },
10883
10926
  {
10884
10927
  "kind": "field",
10885
10928
  "name": "placement",
@@ -2,6 +2,8 @@
2
2
  --width: 31rem;
3
3
  --border-radius: 6px;
4
4
  --padding: 1.5rem;
5
+ --header-padding: var(--padding);
6
+ --footer-padding: var(--padding);
5
7
  --show-duration: 200ms;
6
8
  --hide-duration: 200ms;
7
9
  --backdrop: var(--l-backdrop);
@@ -59,7 +61,7 @@ dialog {
59
61
  justify-content: space-between;
60
62
  align-items: center;
61
63
  gap: 1rem;
62
- padding: var(--padding);
64
+ padding: var(--header-padding);
63
65
  }
64
66
 
65
67
  [part='title'] {
@@ -82,7 +84,7 @@ dialog {
82
84
  display: flex;
83
85
  place-content: end;
84
86
  gap: 0.5rem;
85
- padding: var(--padding);
87
+ padding: var(--footer-padding);
86
88
  }
87
89
 
88
90
  /* Without a header, the body has to provide its own block-start padding
@@ -41,6 +41,7 @@ export declare class Dialog extends LuxenElement {
41
41
  /** Hide the header entirely (title and close slot). */
42
42
  withoutHeader: boolean;
43
43
  dialog: HTMLDialogElement;
44
+ protected _modalKind: 'centered' | 'edge';
44
45
  private _mouseDownTarget;
45
46
  private _commandListener;
46
47
  connectedCallback(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/html/elements/dialog/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAwB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,MAAO,SAAQ,YAAY;IACtC,MAAM,CAAC,MAAM,4BAAwB;IAErC,2CAA2C;IAE3C,KAAK,SAAM;IAEX,kCAAkC;IAElC,IAAI,UAAS;IAEb,0CAA0C;IAE1C,YAAY,UAAS;IAErB,uDAAuD;IAEvD,aAAa,UAAS;IAGtB,MAAM,EAAG,iBAAiB,CAAC;IAE3B,OAAO,CAAC,gBAAgB,CAA4B;IAEpD,OAAO,CAAC,gBAAgB,CAEtB;IAIF,iBAAiB;IAKjB,oBAAoB;IAKpB,YAAY;IASZ,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;IA0BrC,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,eAAe,CAAC,CAAY;IAEpC,OAAO,CAAC,aAAa;YAcP,UAAU;IAUxB,OAAO,CAAC,qBAAqB;IAK7B,MAAM;CA0BP"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/html/elements/dialog/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAgC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,MAAO,SAAQ,YAAY;IACtC,MAAM,CAAC,MAAM,4BAAwB;IAErC,2CAA2C;IAE3C,KAAK,SAAM;IAEX,kCAAkC;IAElC,IAAI,UAAS;IAEb,0CAA0C;IAE1C,YAAY,UAAS;IAErB,uDAAuD;IAEvD,aAAa,UAAS;IAGtB,MAAM,EAAG,iBAAiB,CAAC;IAI3B,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAc;IAEvD,OAAO,CAAC,gBAAgB,CAA4B;IAEpD,OAAO,CAAC,gBAAgB,CAEtB;IAIF,iBAAiB;IAKjB,oBAAoB;IAKpB,YAAY;IASZ,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;IA0BrC,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,eAAe,CAAC,CAAY;IAEpC,OAAO,CAAC,aAAa;YAcP,UAAU;IAUxB,OAAO,CAAC,qBAAqB;IAK7B,MAAM;CA0BP"}
@@ -14,10 +14,18 @@ const supportsClosedBy = typeof HTMLDialogElement !== 'undefined' && 'closedBy'
14
14
  // `:has()` to freeze the root scroll container whenever any modal l-dialog
15
15
  // is open. Purely declarative — no manual lock/unlock bookkeeping.
16
16
  // Symbol guard makes the injection idempotent across HMR reloads.
17
+ //
18
+ // `scrollbar-gutter: stable` only applies to centered modals — it prevents
19
+ // the page behind from shifting horizontally when the scrollbar disappears.
20
+ // Edge-attached modals (drawers) opt out via `data-modal="edge"`: a reserved
21
+ // gutter would push the drawer off the actual viewport edge.
17
22
  const SCROLL_LOCK_SHEET = Symbol.for('luxen-dialog-scroll-lock');
18
23
  if (typeof document !== 'undefined' && !(SCROLL_LOCK_SHEET in document)) {
19
24
  const sheet = new CSSStyleSheet();
20
- sheet.replaceSync(`html:has([data-modal]) { overflow: hidden; scrollbar-gutter: stable; }`);
25
+ sheet.replaceSync(`
26
+ html:has([data-modal]) { overflow: hidden; }
27
+ html:has([data-modal="centered"]) { scrollbar-gutter: stable; }
28
+ `);
21
29
  document.adoptedStyleSheets.push(sheet);
22
30
  Object.defineProperty(document, SCROLL_LOCK_SHEET, { value: sheet });
23
31
  }
@@ -62,6 +70,9 @@ export class Dialog extends LuxenElement {
62
70
  this.lightDismiss = false;
63
71
  /** Hide the header entirely (title and close slot). */
64
72
  this.withoutHeader = false;
73
+ // Drives the scroll-lock stylesheet: `centered` reserves the scrollbar
74
+ // gutter (no page shift); `edge` skips it (drawers sit flush to the edge).
75
+ this._modalKind = 'centered';
65
76
  this._mouseDownTarget = null;
66
77
  this._commandListener = {
67
78
  handleEvent: (e) => this._onCommand(e),
@@ -90,7 +101,7 @@ export class Dialog extends LuxenElement {
90
101
  if (this.open && !this.dialog.open) {
91
102
  // Opening — not cancelable.
92
103
  this.emit('show');
93
- this.toggleAttribute('data-modal', true);
104
+ this.setAttribute('data-modal', this._modalKind);
94
105
  this.dialog.showModal();
95
106
  this._focusAutofocusTarget();
96
107
  void this._emitAfter('after-show');
@@ -1,6 +1,6 @@
1
1
  :host {
2
2
  --size: 320px;
3
- --border-radius: 0.75rem;
3
+ --border-radius: 0.375rem;
4
4
  }
5
5
 
6
6
  /* Override dialog's opacity fade with a slide from the inline-start edge. */
@@ -16,7 +16,7 @@ import { Dialog } from '../dialog/dialog.js';
16
16
  * @csspart footer - The footer wrapper around the footer slot.
17
17
  *
18
18
  * @cssproperty --size - Drawer size on the axis perpendicular to its edge (width for `start`/`end`, height for `bottom`). Default `320px`.
19
- * @cssproperty --border-radius - Drawer border radius on the inner edges. Default `0.75rem`.
19
+ * @cssproperty --border-radius - Drawer border radius on the inner edges. Default `0.375rem`.
20
20
  * @cssproperty --show-duration - Open transition duration. Default `200ms`.
21
21
  * @cssproperty --hide-duration - Close transition duration. Default `200ms`.
22
22
  * @cssproperty --backdrop - Backdrop color.
@@ -28,6 +28,7 @@ import { Dialog } from '../dialog/dialog.js';
28
28
  */
29
29
  export declare class Drawer extends Dialog {
30
30
  static styles: import("lit").CSSResult[];
31
+ protected _modalKind: "edge";
31
32
  /** Edge the drawer slides in from. Defaults to the start (inline-start) edge. */
32
33
  placement?: 'start' | 'end' | 'bottom';
33
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../../../src/html/elements/drawer/drawer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAM7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,MAAO,SAAQ,MAAM;IAChC,OAAgB,MAAM,4BAA4C;IAElE,iFAAiF;IAEjF,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;CACxC"}
1
+ {"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../../../src/html/elements/drawer/drawer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAM7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,MAAO,SAAQ,MAAM;IAChC,OAAgB,MAAM,4BAA4C;IAIlE,UAAmB,UAAU,EAAG,MAAM,CAAU;IAEhD,iFAAiF;IAEjF,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;CACxC"}
@@ -28,7 +28,7 @@ const drawerStyles = unsafeCSS(rawDrawerStyles);
28
28
  * @csspart footer - The footer wrapper around the footer slot.
29
29
  *
30
30
  * @cssproperty --size - Drawer size on the axis perpendicular to its edge (width for `start`/`end`, height for `bottom`). Default `320px`.
31
- * @cssproperty --border-radius - Drawer border radius on the inner edges. Default `0.75rem`.
31
+ * @cssproperty --border-radius - Drawer border radius on the inner edges. Default `0.375rem`.
32
32
  * @cssproperty --show-duration - Open transition duration. Default `200ms`.
33
33
  * @cssproperty --hide-duration - Close transition duration. Default `200ms`.
34
34
  * @cssproperty --backdrop - Backdrop color.
@@ -39,6 +39,12 @@ const drawerStyles = unsafeCSS(rawDrawerStyles);
39
39
  * @event after-hide - Fired after the close animation completes.
40
40
  */
41
41
  export class Drawer extends Dialog {
42
+ constructor() {
43
+ super(...arguments);
44
+ // Edge-attached: opt out of the centered modal's stable scrollbar gutter,
45
+ // which would otherwise push the drawer off the actual viewport edge.
46
+ this._modalKind = 'edge';
47
+ }
42
48
  }
43
49
  Drawer.styles = [hostStyles, dialogStyles, drawerStyles];
44
50
  __decorate([
@@ -19,7 +19,14 @@ Pick a visual style via `data-appearance`. Each appearance has its own CSS impor
19
19
 
20
20
  #### Ring
21
21
 
22
- <ComponentWrapper :html="'<button type=&quot;button&quot; class=&quot;l-close&quot; data-appearance=&quot;ring&quot; aria-label=&quot;Close&quot;></button>'" />
22
+ ```html
23
+ <button
24
+ type="button"
25
+ class="l-close"
26
+ data-appearance="ring"
27
+ aria-label="Close"
28
+ ></button>
29
+ ```
23
30
 
24
31
  ```css
25
32
  @import 'luxen-ui/css/close-button/ring';
@@ -27,7 +34,14 @@ Pick a visual style via `data-appearance`. Each appearance has its own CSS impor
27
34
 
28
35
  #### Square
29
36
 
30
- <ComponentWrapper :html="'<button type=&quot;button&quot; class=&quot;l-close&quot; data-appearance=&quot;square&quot; aria-label=&quot;Close&quot;></button>'" />
37
+ ```html
38
+ <button
39
+ type="button"
40
+ class="l-close"
41
+ data-appearance="square"
42
+ aria-label="Close"
43
+ ></button>
44
+ ```
31
45
 
32
46
  ```css
33
47
  @import 'luxen-ui/css/close-button/square';
@@ -35,7 +49,14 @@ Pick a visual style via `data-appearance`. Each appearance has its own CSS impor
35
49
 
36
50
  #### Circle
37
51
 
38
- <ComponentWrapper :html="'<button type=&quot;button&quot; class=&quot;l-close&quot; data-appearance=&quot;circle&quot; aria-label=&quot;Close&quot;></button>'" />
52
+ ```html
53
+ <button
54
+ type="button"
55
+ class="l-close"
56
+ data-appearance="circle"
57
+ aria-label="Close"
58
+ ></button>
59
+ ```
39
60
 
40
61
  ```css
41
62
  @import 'luxen-ui/css/close-button/circle';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luxen-ui",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Modern web components and CSS-first UI library built with Lit. Framework-agnostic, customizable prefix, design tokens.",
5
5
  "keywords": [
6
6
  "custom-elements",