contain-css-svelte 1.1.17 → 1.1.19

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 (56) hide show
  1. package/dist/Card.svelte +17 -1
  2. package/dist/controls/Button.svelte +9 -1
  3. package/dist/controls/ButtonLink.svelte +9 -1
  4. package/dist/controls/Checkbox.svelte +8 -0
  5. package/dist/controls/CircleButton.svelte +9 -1
  6. package/dist/controls/Input.svelte +9 -1
  7. package/dist/controls/RadioButton.svelte +8 -0
  8. package/dist/controls/Select.svelte +8 -0
  9. package/dist/controls/Slider.svelte +9 -1
  10. package/dist/controls/TabItem.svelte +9 -1
  11. package/dist/controls/Toggle.svelte +9 -1
  12. package/dist/dropdowns/DropdownMenu.svelte +9 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/layout/Accordion.svelte +9 -1
  15. package/dist/layout/Bar.svelte +34 -7
  16. package/dist/layout/Column.svelte.d.ts +2 -1
  17. package/dist/layout/ColumnContainer.svelte +20 -3
  18. package/dist/layout/ColumnContainer.svelte.d.ts +2 -1
  19. package/dist/layout/Columns.svelte +9 -1
  20. package/dist/layout/Container.svelte +20 -5
  21. package/dist/layout/Container.svelte.d.ts +2 -1
  22. package/dist/layout/DataList.svelte +9 -1
  23. package/dist/layout/DataListItem.svelte +9 -1
  24. package/dist/layout/Fieldset.svelte +9 -1
  25. package/dist/layout/Form.svelte +9 -1
  26. package/dist/layout/FormItem.svelte +9 -1
  27. package/dist/layout/GridLayout.svelte +19 -2
  28. package/dist/layout/GridLayout.svelte.d.ts +2 -1
  29. package/dist/layout/Hero.svelte +9 -1
  30. package/dist/layout/Inline.svelte +15 -1
  31. package/dist/layout/Inline.svelte.d.ts +2 -2
  32. package/dist/layout/MenuList.svelte +9 -1
  33. package/dist/layout/Page.svelte +9 -1
  34. package/dist/layout/Row.svelte.d.ts +2 -1
  35. package/dist/layout/RowContainer.svelte +20 -3
  36. package/dist/layout/RowContainer.svelte.d.ts +2 -1
  37. package/dist/layout/Sidebar.svelte +8 -0
  38. package/dist/layout/SplitPane.svelte +9 -1
  39. package/dist/layout/Stack.svelte +25 -2
  40. package/dist/layout/Stack.svelte.d.ts +2 -2
  41. package/dist/layout/TabBar.svelte +9 -1
  42. package/dist/layout/Table.svelte +9 -1
  43. package/dist/layout/Tile.svelte +18 -2
  44. package/dist/layout/Tile.svelte.d.ts +2 -2
  45. package/dist/misc/CodeInner.svelte +9 -1
  46. package/dist/misc/Progress.svelte +9 -1
  47. package/dist/misc/Tag.svelte +11 -1
  48. package/dist/overlays/Dialog.svelte +9 -1
  49. package/dist/overlays/Tooltip.svelte +9 -1
  50. package/dist/sass/_box.scss +15 -0
  51. package/dist/types.d.ts +26 -4
  52. package/dist/typography/TextLayout.svelte +23 -6
  53. package/dist/typography/TextLayout.svelte.d.ts +2 -1
  54. package/dist/vars/defaults.css +20 -1
  55. package/dist/vars/layout.css +20 -1
  56. package/package.json +1 -1
package/dist/Card.svelte CHANGED
@@ -6,6 +6,8 @@ const cssVars = $derived(injectVars({ height, ...restProps }, "card", [
6
6
  "padding",
7
7
  "width",
8
8
  "height",
9
+ "marginBlock",
10
+ "marginInline",
9
11
  ]));
10
12
  const forceFixedHeight = (h) => {
11
13
  if (h && !fixedHeight) {
@@ -30,6 +32,14 @@ let hasFooter = $derived(Boolean(footer));
30
32
  </div>
31
33
 
32
34
  <style>@charset "UTF-8";
35
+ /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
36
+ one value (both sides equal) or two (start end), so there is no separate
37
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
38
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
39
+ appeared by default on every consumer would be a silent layout change the
40
+ day this mixin got added to a new component. Callers opt in with an actual
41
+ value. (Container does not use this mixin: it wants --gap/auto as its
42
+ defaults, which do not fit the "0 unless asked" contract here.) */
33
43
  /* Warning: because we define a fallback
34
44
  media query, the media query can override the container
35
45
  if we stack a bunch of these in a row and aren't thoughtful about the order.
@@ -46,7 +56,13 @@ let hasFooter = $derived(Boolean(footer));
46
56
  overflow-x: hidden;
47
57
  container-type: inline-size;
48
58
  width: var(--w);
49
- margin: var(--card-margin, var(--margin, 16px));
59
+ /* Was a single `margin` shorthand (--card-margin, 16px on every side).
60
+ Split into block/inline -- same default on each axis, so nothing
61
+ visually changes for existing callers -- but now a caller who wants
62
+ a header Card flush against the content below it, say, can set just
63
+ one axis instead of fighting a 4-value margin shorthand. */
64
+ margin-block: var(--card-margin-block, var(--margin-block, 16px));
65
+ margin-inline: var(--card-margin-inline, var(--margin-inline, 16px));
50
66
  border-radius: var(--card-border-radius, var(--surface-border-radius, var(--border-radius, 0)));
51
67
  border: var(--card-border, var(--surface-border, var(--border, var(--border-width) var(--border-style) var(--border-color))));
52
68
  --link-bg: var(--card-link-bg, var(--surface-link-bg, inherit));
@@ -22,7 +22,15 @@ const style = $derived(injectVars(restProps, "button", ["bg", "fg", "padding", "
22
22
  {/if}
23
23
  </button>
24
24
 
25
- <style>/* Warning: because we define a fallback
25
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
26
+ one value (both sides equal) or two (start end), so there is no separate
27
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
28
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
29
+ appeared by default on every consumer would be a silent layout change the
30
+ day this mixin got added to a new component. Callers opt in with an actual
31
+ value. (Container does not use this mixin: it wants --gap/auto as its
32
+ defaults, which do not fit the "0 unless asked" contract here.) */
33
+ /* Warning: because we define a fallback
26
34
  media query, the media query can override the container
27
35
  if we stack a bunch of these in a row and aren't thoughtful about the order.
28
36
  Put min-width queries *after* max-width queries so that smaller
@@ -35,7 +35,15 @@ const iconSlotted = $derived(Boolean(icon));
35
35
  </span>
36
36
  </a>
37
37
 
38
- <style>/* Warning: because we define a fallback
38
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
39
+ one value (both sides equal) or two (start end), so there is no separate
40
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
41
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
42
+ appeared by default on every consumer would be a silent layout change the
43
+ day this mixin got added to a new component. Callers opt in with an actual
44
+ value. (Container does not use this mixin: it wants --gap/auto as its
45
+ defaults, which do not fit the "0 unless asked" contract here.) */
46
+ /* Warning: because we define a fallback
39
47
  media query, the media query can override the container
40
48
  if we stack a bunch of these in a row and aren't thoughtful about the order.
41
49
  Put min-width queries *after* max-width queries so that smaller
@@ -57,6 +57,14 @@ let ref = $state(null);
57
57
  </div>
58
58
 
59
59
  <style>@charset "UTF-8";
60
+ /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
61
+ one value (both sides equal) or two (start end), so there is no separate
62
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
63
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
64
+ appeared by default on every consumer would be a silent layout change the
65
+ day this mixin got added to a new component. Callers opt in with an actual
66
+ value. (Container does not use this mixin: it wants --gap/auto as its
67
+ defaults, which do not fit the "0 unless asked" contract here.) */
60
68
  /* Warning: because we define a fallback
61
69
  media query, the media query can override the container
62
70
  if we stack a bunch of these in a row and aren't thoughtful about the order.
@@ -22,7 +22,15 @@ const style = $derived(injectVars(restProps, "mini-button", [
22
22
  {@render children?.()}
23
23
  </button>
24
24
 
25
- <style>/* Warning: because we define a fallback
25
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
26
+ one value (both sides equal) or two (start end), so there is no separate
27
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
28
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
29
+ appeared by default on every consumer would be a silent layout change the
30
+ day this mixin got added to a new component. Callers opt in with an actual
31
+ value. (Container does not use this mixin: it wants --gap/auto as its
32
+ defaults, which do not fit the "0 unless asked" contract here.) */
33
+ /* Warning: because we define a fallback
26
34
  media query, the media query can override the container
27
35
  if we stack a bunch of these in a row and aren't thoughtful about the order.
28
36
  Put min-width queries *after* max-width queries so that smaller
@@ -4,7 +4,15 @@ export {};
4
4
 
5
5
  <input bind:value {placeholder} {...restProps} />
6
6
 
7
- <style>/* Warning: because we define a fallback
7
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
8
+ one value (both sides equal) or two (start end), so there is no separate
9
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
10
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
11
+ appeared by default on every consumer would be a silent layout change the
12
+ day this mixin got added to a new component. Callers opt in with an actual
13
+ value. (Container does not use this mixin: it wants --gap/auto as its
14
+ defaults, which do not fit the "0 unless asked" contract here.) */
15
+ /* Warning: because we define a fallback
8
16
  media query, the media query can override the container
9
17
  if we stack a bunch of these in a row and aren't thoughtful about the order.
10
18
  Put min-width queries *after* max-width queries so that smaller
@@ -35,6 +35,14 @@ function handleChange() {
35
35
  </div>
36
36
 
37
37
  <style>@charset "UTF-8";
38
+ /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
39
+ one value (both sides equal) or two (start end), so there is no separate
40
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
41
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
42
+ appeared by default on every consumer would be a silent layout change the
43
+ day this mixin got added to a new component. Callers opt in with an actual
44
+ value. (Container does not use this mixin: it wants --gap/auto as its
45
+ defaults, which do not fit the "0 unless asked" contract here.) */
38
46
  /* Warning: because we define a fallback
39
47
  media query, the media query can override the container
40
48
  if we stack a bunch of these in a row and aren't thoughtful about the order.
@@ -129,6 +129,14 @@ $effect(() => {
129
129
  </div>
130
130
 
131
131
  <style>@charset "UTF-8";
132
+ /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
133
+ one value (both sides equal) or two (start end), so there is no separate
134
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
135
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
136
+ appeared by default on every consumer would be a silent layout change the
137
+ day this mixin got added to a new component. Callers opt in with an actual
138
+ value. (Container does not use this mixin: it wants --gap/auto as its
139
+ defaults, which do not fit the "0 unless asked" contract here.) */
132
140
  /* Warning: because we define a fallback
133
141
  media query, the media query can override the container
134
142
  if we stack a bunch of these in a row and aren't thoughtful about the order.
@@ -23,7 +23,15 @@ const style = $derived(`${injectVars(elementProps, "slider", ["bg", "fg", "paddi
23
23
  {...elementProps}
24
24
  />
25
25
 
26
- <style>/* Warning: because we define a fallback
26
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
27
+ one value (both sides equal) or two (start end), so there is no separate
28
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
29
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
30
+ appeared by default on every consumer would be a silent layout change the
31
+ day this mixin got added to a new component. Callers opt in with an actual
32
+ value. (Container does not use this mixin: it wants --gap/auto as its
33
+ defaults, which do not fit the "0 unless asked" contract here.) */
34
+ /* Warning: because we define a fallback
27
35
  media query, the media query can override the container
28
36
  if we stack a bunch of these in a row and aren't thoughtful about the order.
29
37
  Put min-width queries *after* max-width queries so that smaller
@@ -10,7 +10,15 @@ const style = $derived(injectVars(restProps, "tab", ["bg", "fg", "padding", "wid
10
10
  </Button>
11
11
  </div>
12
12
 
13
- <style>/* Warning: because we define a fallback
13
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
14
+ one value (both sides equal) or two (start end), so there is no separate
15
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
16
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
17
+ appeared by default on every consumer would be a silent layout change the
18
+ day this mixin got added to a new component. Callers opt in with an actual
19
+ value. (Container does not use this mixin: it wants --gap/auto as its
20
+ defaults, which do not fit the "0 unless asked" contract here.) */
21
+ /* Warning: because we define a fallback
14
22
  media query, the media query can override the container
15
23
  if we stack a bunch of these in a row and aren't thoughtful about the order.
16
24
  Put min-width queries *after* max-width queries so that smaller
@@ -30,7 +30,15 @@ const effectiveOnLabel = $derived(onLabel || children);
30
30
  {/if}
31
31
  </label>
32
32
 
33
- <style>/* Warning: because we define a fallback
33
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
34
+ one value (both sides equal) or two (start end), so there is no separate
35
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
36
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
37
+ appeared by default on every consumer would be a silent layout change the
38
+ day this mixin got added to a new component. Callers opt in with an actual
39
+ value. (Container does not use this mixin: it wants --gap/auto as its
40
+ defaults, which do not fit the "0 unless asked" contract here.) */
41
+ /* Warning: because we define a fallback
34
42
  media query, the media query can override the container
35
43
  if we stack a bunch of these in a row and aren't thoughtful about the order.
36
44
  Put min-width queries *after* max-width queries so that smaller
@@ -275,7 +275,15 @@ let popoverDiv = $state();
275
275
  </div>
276
276
  </nav>
277
277
 
278
- <style>/* Warning: because we define a fallback
278
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
279
+ one value (both sides equal) or two (start end), so there is no separate
280
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
281
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
282
+ appeared by default on every consumer would be a silent layout change the
283
+ day this mixin got added to a new component. Callers opt in with an actual
284
+ value. (Container does not use this mixin: it wants --gap/auto as its
285
+ defaults, which do not fit the "0 unless asked" contract here.) */
286
+ /* Warning: because we define a fallback
279
287
  media query, the media query can override the container
280
288
  if we stack a bunch of these in a row and aren't thoughtful about the order.
281
289
  Put min-width queries *after* max-width queries so that smaller
package/dist/index.d.ts CHANGED
@@ -46,7 +46,7 @@ import Table from "./layout/Table.svelte";
46
46
  import Accordion from "./layout/Accordion.svelte";
47
47
  import Tag from "./misc/Tag.svelte";
48
48
  import Text from "./typography/Text.svelte";
49
- export type { BaseStyleProps, ContainerStyleProps, BarStyleProps, MenuStyleProps, CardStyleProps, TagStyleProps, SidebarStyleProps, HeroStyleProps, DropdownMenuStyleProps, } from "./types";
49
+ export type { BaseStyleProps, MarginStyleProps, ContainerStyleProps, BarStyleProps, MenuStyleProps, CardStyleProps, TagStyleProps, SidebarStyleProps, HeroStyleProps, DropdownMenuStyleProps, } from "./types";
50
50
  export { Tag };
51
51
  export { Hero };
52
52
  export { TabItem };
@@ -38,7 +38,15 @@ function onAccordionClicked(e) {
38
38
  {@render children?.()}
39
39
  </div>
40
40
 
41
- <style>/* Warning: because we define a fallback
41
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
42
+ one value (both sides equal) or two (start end), so there is no separate
43
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
44
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
45
+ appeared by default on every consumer would be a silent layout change the
46
+ day this mixin got added to a new component. Callers opt in with an actual
47
+ value. (Container does not use this mixin: it wants --gap/auto as its
48
+ defaults, which do not fit the "0 unless asked" contract here.) */
49
+ /* Warning: because we define a fallback
42
50
  media query, the media query can override the container
43
51
  if we stack a bunch of these in a row and aren't thoughtful about the order.
44
52
  Put min-width queries *after* max-width queries so that smaller
@@ -1,5 +1,23 @@
1
- <script lang="ts">import { injectVars } from "../util";
2
- const { children, primary, secondary, ...restProps } = $props();
1
+ <script module lang="ts">"use strict";
2
+ let warnedDeprecatedMargin = false;
3
+ </script>
4
+
5
+ <script lang="ts">import { BROWSER, DEV } from "esm-env";
6
+ import { injectVars } from "../util";
7
+ const { children, primary, secondary, marginTop, marginBottom, marginBlock, ...restProps } = $props();
8
+ $effect(() => {
9
+ if (BROWSER && DEV && (marginTop != null || marginBottom != null) && !warnedDeprecatedMargin) {
10
+ warnedDeprecatedMargin = true;
11
+ console.warn('[ContainCSS] Bar\'s marginTop/marginBottom props are deprecated. Use marginBlock instead -- e.g. marginBlock="0 1em" is the same as marginTop="0" marginBottom="1em" (the old default).');
12
+ }
13
+ });
14
+ /* marginBlock wins if given explicitly; otherwise compose the deprecated
15
+ pair into the same shape, preserving each side's old default (no space
16
+ above, 1em below) for whichever half was not passed. */
17
+ const resolvedMarginBlock = $derived(marginBlock ??
18
+ (marginTop != null || marginBottom != null
19
+ ? `${marginTop ?? "0"} ${marginBottom ?? "1em"}`
20
+ : null));
3
21
  const cssKeys = [
4
22
  "bg",
5
23
  "fg",
@@ -8,10 +26,10 @@ const cssKeys = [
8
26
  "height",
9
27
  "justify",
10
28
  "align",
11
- "marginBottom",
12
- "marginTop",
29
+ "marginBlock",
30
+ "marginInline",
13
31
  ];
14
- const style = $derived(injectVars(restProps, "bar", cssKeys));
32
+ const style = $derived(injectVars({ ...restProps, marginBlock: resolvedMarginBlock }, "bar", cssKeys));
15
33
  const extraStyle = $derived(primary
16
34
  ? "--bar-bg: var(--primary-bg); --bar-fg: var(--primary-fg);"
17
35
  : secondary
@@ -23,7 +41,15 @@ const extraStyle = $derived(primary
23
41
  {@render children?.()}
24
42
  </div>
25
43
 
26
- <style>/* Warning: because we define a fallback
44
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
45
+ one value (both sides equal) or two (start end), so there is no separate
46
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
47
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
48
+ appeared by default on every consumer would be a silent layout change the
49
+ day this mixin got added to a new component. Callers opt in with an actual
50
+ value. (Container does not use this mixin: it wants --gap/auto as its
51
+ defaults, which do not fit the "0 unless asked" contract here.) */
52
+ /* Warning: because we define a fallback
27
53
  media query, the media query can override the container
28
54
  if we stack a bunch of these in a row and aren't thoughtful about the order.
29
55
  Put min-width queries *after* max-width queries so that smaller
@@ -39,7 +65,8 @@ const extraStyle = $derived(primary
39
65
  padding: var(--bar-padding, var(--padding, 8px));
40
66
  border-bottom: var(--bar-border-bottom, var(--bar-border-width, var(--border-width, 1px)) var(--bar-border-style, var(--border-style, 1px)) var(--bar-border-color, var(--border-color, 1px)));
41
67
  border-top: var(--bar-border-top, var(--bar-border-width, var(--border-width, 1px)) var(--bar-border-style, var(--border-style, 1px)) var(--bar-border-color, var(--border-color, 1px)));
42
- margin-bottom: var(--bar-margin-bottom, 1em);
68
+ margin-block: var(--bar-margin-block, 0 1em);
69
+ margin-inline: var(--bar-margin-inline, 0);
43
70
  min-height: var(--bar-min-height, var(--bar-height, 3em));
44
71
  height: var(--bar-height, auto);
45
72
  max-height: var(--bar-max-height);
@@ -1,10 +1,11 @@
1
1
  import type { Snippet } from "svelte";
2
2
  import type { HTMLAttributes } from "svelte/elements";
3
+ import type { MarginStyleProps } from "../types";
3
4
  type Props = {
4
5
  size?: "small" | "medium" | "large";
5
6
  customWidth?: string | null;
6
7
  children?: Snippet;
7
- } & HTMLAttributes<HTMLElement>;
8
+ } & MarginStyleProps & HTMLAttributes<HTMLElement>;
8
9
  declare const Column: import("svelte").Component<Props, {}, "">;
9
10
  type Column = ReturnType<typeof Column>;
10
11
  export default Column;
@@ -1,5 +1,9 @@
1
- <script lang="ts">let { size = "medium", customWidth = null, children, ...restProps } = $props();
2
- export {};
1
+ <script lang="ts">import { injectVars } from "../util";
2
+ let { size = "medium", customWidth = null, children, marginBlock = null, marginInline = null, style: inlineStyle, ...restProps } = $props();
3
+ const style = $derived(injectVars({ marginBlock, marginInline }, "column-container", [
4
+ "marginBlock",
5
+ "marginInline",
6
+ ]) + (inlineStyle ?? ""));
3
7
  </script>
4
8
 
5
9
  <section
@@ -8,12 +12,21 @@ export {};
8
12
  class:medium={size === "medium"}
9
13
  class:large={size === "large"}
10
14
  style:--custom-width={customWidth}
15
+ {style}
11
16
  {...restProps}
12
17
  >
13
18
  {@render children?.()}
14
19
  </section>
15
20
 
16
- <style>/* Warning: because we define a fallback
21
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
22
+ one value (both sides equal) or two (start end), so there is no separate
23
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
24
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
25
+ appeared by default on every consumer would be a silent layout change the
26
+ day this mixin got added to a new component. Callers opt in with an actual
27
+ value. (Container does not use this mixin: it wants --gap/auto as its
28
+ defaults, which do not fit the "0 unless asked" contract here.) */
29
+ /* Warning: because we define a fallback
17
30
  media query, the media query can override the container
18
31
  if we stack a bunch of these in a row and aren't thoughtful about the order.
19
32
  Put min-width queries *after* max-width queries so that smaller
@@ -41,4 +54,8 @@ export {};
41
54
  overflow: auto;
42
55
  justify-content: start;
43
56
  align-items: var(--column-align, center);
57
+ --_margin-block: var(--column-container-margin-block, var(--margin-block, 0));
58
+ --_margin-inline: var(--column-container-margin-inline, var(--margin-inline, 0));
59
+ margin-block: var(--_margin-block);
60
+ margin-inline: var(--_margin-inline);
44
61
  }</style>
@@ -1,10 +1,11 @@
1
1
  import type { Snippet } from "svelte";
2
2
  import type { HTMLAttributes } from "svelte/elements";
3
+ import type { MarginStyleProps } from "../types";
3
4
  type Props = {
4
5
  size?: "small" | "medium" | "large";
5
6
  customWidth?: string | null;
6
7
  children?: Snippet;
7
- } & HTMLAttributes<HTMLElement>;
8
+ } & MarginStyleProps & HTMLAttributes<HTMLElement>;
8
9
  declare const ColumnContainer: import("svelte").Component<Props, {}, "">;
9
10
  type ColumnContainer = ReturnType<typeof ColumnContainer>;
10
11
  export default ColumnContainer;
@@ -6,7 +6,15 @@ let { children } = $props();
6
6
  {@render children?.()}
7
7
  </div>
8
8
 
9
- <style>/* Warning: because we define a fallback
9
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
10
+ one value (both sides equal) or two (start end), so there is no separate
11
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
12
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
13
+ appeared by default on every consumer would be a silent layout change the
14
+ day this mixin got added to a new component. Callers opt in with an actual
15
+ value. (Container does not use this mixin: it wants --gap/auto as its
16
+ defaults, which do not fit the "0 unless asked" contract here.) */
17
+ /* Warning: because we define a fallback
10
18
  media query, the media query can override the container
11
19
  if we stack a bunch of these in a row and aren't thoughtful about the order.
12
20
  Put min-width queries *after* max-width queries so that smaller
@@ -3,7 +3,8 @@ const { children, border = false, ...props } = $props();
3
3
  const style = $derived(injectVars(props, "container", [
4
4
  "bg",
5
5
  "fg",
6
- "margin",
6
+ "marginBlock",
7
+ "marginInline",
7
8
  "maxWidth",
8
9
  "padding",
9
10
  "height",
@@ -16,7 +17,15 @@ const style = $derived(injectVars(props, "container", [
16
17
  {@render children?.()}
17
18
  </section>
18
19
 
19
- <style>/* Warning: because we define a fallback
20
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
21
+ one value (both sides equal) or two (start end), so there is no separate
22
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
23
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
24
+ appeared by default on every consumer would be a silent layout change the
25
+ day this mixin got added to a new component. Callers opt in with an actual
26
+ value. (Container does not use this mixin: it wants --gap/auto as its
27
+ defaults, which do not fit the "0 unless asked" contract here.) */
28
+ /* Warning: because we define a fallback
20
29
  media query, the media query can override the container
21
30
  if we stack a bunch of these in a row and aren't thoughtful about the order.
22
31
  Put min-width queries *after* max-width queries so that smaller
@@ -24,7 +33,6 @@ const style = $derived(injectVars(props, "container", [
24
33
  */
25
34
  /* Convenience groupings */
26
35
  section {
27
- margin: auto;
28
36
  box-sizing: border-box;
29
37
  padding: var(--container-padding, var(--surface-padding, var(--padding, 8px)));
30
38
  --link-bg: var(--container-link-bg, var(--surface-link-bg, var(--block-link-bg, inherit)));
@@ -435,8 +443,15 @@ section :global(h6 + p::first-letter) {
435
443
  section {
436
444
  /* Override typography max-width */
437
445
  max-width: var(--container-max-width, var(--surface-max-width, var(--block-max-width, var(--max-width, 900px))));
438
- margin-top: var(--container-margin, var(--surface-margin, var(--block-margin, var(--margin, var(--gap)))));
439
- margin-bottom: var(--container-margin, var(--surface-margin, var(--block-margin, var(--margin, var(--gap)))));
446
+ /* Not the generic margin-props() mixin (_box.scss): that defaults to 0,
447
+ but a Container has always centred itself horizontally and kept a
448
+ gap's worth of vertical rhythm above/below by default. Same defaults,
449
+ same var-with-fallbacks() prefix chain as everything else here --
450
+ just block/inline now instead of one `margin` prop, so a caller can
451
+ set only one axis (a Container flush against a footer, say) instead
452
+ of fighting a single shared value for both. */
453
+ margin-inline: var(--container-margin-inline, var(--surface-margin-inline, var(--block-margin-inline, var(--margin-inline, auto))));
454
+ margin-block: var(--container-margin-block, var(--surface-margin-block, var(--block-margin-block, var(--margin-block, var(--gap)))));
440
455
  /* Why is this suddenly causing a scroll? */
441
456
  container-type: inline-size;
442
457
  overflow-x: hidden;
@@ -3,7 +3,8 @@ import type { HTMLAttributes } from "svelte/elements";
3
3
  type Props = {
4
4
  bg?: string | null;
5
5
  fg?: string | null;
6
- margin?: string | null;
6
+ marginBlock?: string | null;
7
+ marginInline?: string | null;
7
8
  maxWidth?: string | null;
8
9
  padding?: string | null;
9
10
  height?: string | null;
@@ -36,7 +36,15 @@ const style = $derived(injectVars(restProps, "data-list", [
36
36
  {@render children?.()}
37
37
  </ul>
38
38
 
39
- <style>/* Warning: because we define a fallback
39
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
40
+ one value (both sides equal) or two (start end), so there is no separate
41
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
42
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
43
+ appeared by default on every consumer would be a silent layout change the
44
+ day this mixin got added to a new component. Callers opt in with an actual
45
+ value. (Container does not use this mixin: it wants --gap/auto as its
46
+ defaults, which do not fit the "0 unless asked" contract here.) */
47
+ /* Warning: because we define a fallback
40
48
  media query, the media query can override the container
41
49
  if we stack a bunch of these in a row and aren't thoughtful about the order.
42
50
  Put min-width queries *after* max-width queries so that smaller
@@ -116,7 +116,15 @@ function handleKeydown(event) {
116
116
  {/if}
117
117
  </li>
118
118
 
119
- <style>/* Warning: because we define a fallback
119
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
120
+ one value (both sides equal) or two (start end), so there is no separate
121
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
122
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
123
+ appeared by default on every consumer would be a silent layout change the
124
+ day this mixin got added to a new component. Callers opt in with an actual
125
+ value. (Container does not use this mixin: it wants --gap/auto as its
126
+ defaults, which do not fit the "0 unless asked" contract here.) */
127
+ /* Warning: because we define a fallback
120
128
  media query, the media query can override the container
121
129
  if we stack a bunch of these in a row and aren't thoughtful about the order.
122
130
  Put min-width queries *after* max-width queries so that smaller
@@ -46,7 +46,15 @@ const style = $derived(injectVars({
46
46
  </fieldset>
47
47
  </FormProvider>
48
48
 
49
- <style>/* Warning: because we define a fallback
49
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
50
+ one value (both sides equal) or two (start end), so there is no separate
51
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
52
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
53
+ appeared by default on every consumer would be a silent layout change the
54
+ day this mixin got added to a new component. Callers opt in with an actual
55
+ value. (Container does not use this mixin: it wants --gap/auto as its
56
+ defaults, which do not fit the "0 unless asked" contract here.) */
57
+ /* Warning: because we define a fallback
50
58
  media query, the media query can override the container
51
59
  if we stack a bunch of these in a row and aren't thoughtful about the order.
52
60
  Put min-width queries *after* max-width queries so that smaller
@@ -43,7 +43,15 @@ const style = $derived(injectVars({
43
43
  </form>
44
44
  </FormProvider>
45
45
 
46
- <style>/* Warning: because we define a fallback
46
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
47
+ one value (both sides equal) or two (start end), so there is no separate
48
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
49
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
50
+ appeared by default on every consumer would be a silent layout change the
51
+ day this mixin got added to a new component. Callers opt in with an actual
52
+ value. (Container does not use this mixin: it wants --gap/auto as its
53
+ defaults, which do not fit the "0 unless asked" contract here.) */
54
+ /* Warning: because we define a fallback
47
55
  media query, the media query can override the container
48
56
  if we stack a bunch of these in a row and aren't thoughtful about the order.
49
57
  Put min-width queries *after* max-width queries so that smaller
@@ -36,7 +36,15 @@ const effectiveLayout = $derived(above ? "above" : below ? "below" : effectiveLa
36
36
  <div class="after">{@render after?.()}</div>
37
37
  </div>
38
38
 
39
- <style>/* Warning: because we define a fallback
39
+ <style>/* Logical, not top/bottom/left/right: margin-block/margin-inline already take
40
+ one value (both sides equal) or two (start end), so there is no separate
41
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
42
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
43
+ appeared by default on every consumer would be a silent layout change the
44
+ day this mixin got added to a new component. Callers opt in with an actual
45
+ value. (Container does not use this mixin: it wants --gap/auto as its
46
+ defaults, which do not fit the "0 unless asked" contract here.) */
47
+ /* Warning: because we define a fallback
40
48
  media query, the media query can override the container
41
49
  if we stack a bunch of these in a row and aren't thoughtful about the order.
42
50
  Put min-width queries *after* max-width queries so that smaller
@@ -1,17 +1,30 @@
1
- <script lang="ts">let { children, card = false, tile = false, ...restProps } = $props();
2
- export {};
1
+ <script lang="ts">import { injectVars } from "../util";
2
+ let { children, card = false, tile = false, marginBlock = null, marginInline = null, style: inlineStyle, ...restProps } = $props();
3
+ const style = $derived(injectVars({ marginBlock, marginInline }, "grid-layout", [
4
+ "marginBlock",
5
+ "marginInline",
6
+ ]) + (inlineStyle ?? ""));
3
7
  </script>
4
8
 
5
9
  <div
6
10
  class="grid-layout"
7
11
  class:card-grid={card}
8
12
  class:tile-grid={tile}
13
+ {style}
9
14
  {...restProps}
10
15
  >
11
16
  {@render children?.()}
12
17
  </div>
13
18
 
14
19
  <style>@charset "UTF-8";
20
+ /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
21
+ one value (both sides equal) or two (start end), so there is no separate
22
+ "which side" prop to remember and no 4-value shorthand order to get wrong.
23
+ Defaults to 0 on purpose -- unlike padding-props above, a margin that
24
+ appeared by default on every consumer would be a silent layout change the
25
+ day this mixin got added to a new component. Callers opt in with an actual
26
+ value. (Container does not use this mixin: it wants --gap/auto as its
27
+ defaults, which do not fit the "0 unless asked" contract here.) */
15
28
  /* Warning: because we define a fallback
16
29
  media query, the media query can override the container
17
30
  if we stack a bunch of these in a row and aren't thoughtful about the order.
@@ -85,6 +98,10 @@ export {};
85
98
  border-bottom: var(--grid-layout-border-bottom, var(--border-bottom, var(--grid-layout-border, var(--border, none))));
86
99
  border-left: var(--grid-layout-border-left, var(--border-left, var(--grid-layout-border, var(--border, none))));
87
100
  border-radius: var(--grid-layout-border-radius, var(--border-radius, none));
101
+ --_margin-block: var(--grid-layout-margin-block, var(--margin-block, 0));
102
+ --_margin-inline: var(--grid-layout-margin-inline, var(--margin-inline, 0));
103
+ margin-block: var(--_margin-block);
104
+ margin-inline: var(--_margin-inline);
88
105
  }
89
106
 
90
107
  /* Escape hatch for the things in a grid that are not items in the run: a
@@ -1,10 +1,11 @@
1
1
  import type { Snippet } from "svelte";
2
2
  import type { HTMLAttributes } from "svelte/elements";
3
+ import type { MarginStyleProps } from "../types";
3
4
  type Props = {
4
5
  card?: boolean;
5
6
  tile?: boolean;
6
7
  children?: Snippet;
7
- } & HTMLAttributes<HTMLDivElement>;
8
+ } & MarginStyleProps & HTMLAttributes<HTMLDivElement>;
8
9
  declare const GridLayout: import("svelte").Component<Props, {}, "">;
9
10
  type GridLayout = ReturnType<typeof GridLayout>;
10
11
  export default GridLayout;