@abcnews/components-builder 0.0.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 (32) hide show
  1. package/README.md +134 -0
  2. package/dist/BuilderStyleRoot/BuilderStyleRoot.svelte +175 -0
  3. package/dist/BuilderStyleRoot/BuilderStyleRoot.svelte.d.ts +5 -0
  4. package/dist/ContextMenu/ContextMenu.stories.svelte +66 -0
  5. package/dist/ContextMenu/ContextMenu.stories.svelte.d.ts +27 -0
  6. package/dist/ContextMenu/ContextMenu.svelte +111 -0
  7. package/dist/ContextMenu/ContextMenu.svelte.d.ts +7 -0
  8. package/dist/GoogleDocScrollyteller/GoogleDocScrollyteller.stories.svelte +24 -0
  9. package/dist/GoogleDocScrollyteller/GoogleDocScrollyteller.stories.svelte.d.ts +27 -0
  10. package/dist/GoogleDocScrollyteller/GoogleDocScrollyteller.svelte +211 -0
  11. package/dist/GoogleDocScrollyteller/GoogleDocScrollyteller.svelte.d.ts +9 -0
  12. package/dist/GoogleDocScrollyteller/utils.d.ts +23 -0
  13. package/dist/GoogleDocScrollyteller/utils.js +94 -0
  14. package/dist/Modal/Modal.stories.svelte +32 -0
  15. package/dist/Modal/Modal.stories.svelte.d.ts +27 -0
  16. package/dist/Modal/Modal.svelte +116 -0
  17. package/dist/Modal/Modal.svelte.d.ts +8 -0
  18. package/dist/ScreenshotTool/ScreenshotTool.stories.svelte +26 -0
  19. package/dist/ScreenshotTool/ScreenshotTool.stories.svelte.d.ts +27 -0
  20. package/dist/ScreenshotTool/ScreenshotTool.svelte +292 -0
  21. package/dist/ScreenshotTool/ScreenshotTool.svelte.d.ts +17 -0
  22. package/dist/Typeahead/Typeahead.stories.svelte +26 -0
  23. package/dist/Typeahead/Typeahead.stories.svelte.d.ts +27 -0
  24. package/dist/Typeahead/Typeahead.svelte +177 -0
  25. package/dist/Typeahead/Typeahead.svelte.d.ts +12 -0
  26. package/dist/UpdateChecker/UpdateChecker.stories.svelte +27 -0
  27. package/dist/UpdateChecker/UpdateChecker.stories.svelte.d.ts +27 -0
  28. package/dist/UpdateChecker/UpdateChecker.svelte +127 -0
  29. package/dist/UpdateChecker/UpdateChecker.svelte.d.ts +11 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +2 -0
  32. package/package.json +71 -0
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # components-builder
2
+
3
+ A set of common styles and components for creating builders - tools to configure and preview visualisations with a GUI interface.
4
+
5
+ **These components are not thoroughly tested as a library, and are provided as-is. Please contribute pull requests to fix issues**
6
+
7
+ ## Global Styles (BuilderStyleRoot)
8
+
9
+ This project uses global styles in the same way as bootstrap or tailwind. These styles mainly focus on form elements and things you'll likely to hit in a builder.
10
+
11
+ Wrap your application inside of the BuilderStyleRoot component to make use of these styles. Note that all the components in this repository also depend on these styles.
12
+
13
+ ## UpdateChecker
14
+
15
+ The update checker extracts the current version number from the URL, and recursively checks for new versions, major, minor, and patch. If a new version is found it will show a modal prompting the user to update.
16
+
17
+ Please ensure all your application state is kept in the URL, otherwise it may be lost on upgrade.
18
+
19
+ ## ScreenshotTool (fallback images)
20
+
21
+ The screenshot tool allows users to paste an entire article, then extracts all the markers and sends them to a third-party service to screenshot.
22
+
23
+ For this to work you must set up a standalone page that can display the visualisation that the external service to screenshot, similar to how you would develop an iframe version of the visualisation.
24
+
25
+ Note that the screenshot tool is not fast. We haven't been able to speed up the server side enough to make this a great experience.
26
+
27
+ ## Typeahead
28
+
29
+ The typeahead component uses a native HTML input element, in conjunction with the datalist element, to provide native searching and keyboard accessibility. The component implements its own multi-select functionality as that isn't available natively.
30
+
31
+ ```svelte
32
+ <Typeahead
33
+ {disabled}
34
+ values={[{value: 'bne', label: 'Brisbane'},{value: 'syd', label: 'Sydney'}]}
35
+ value={['bne']}
36
+ onChange={newValue => console.log(newValue)}
37
+ ```
38
+
39
+ ## ContextMenu
40
+
41
+ The context menu component uses a native dialog element and provides a number of classes for you to style the contents of your menu. Check the storybook for more examples of these.
42
+
43
+ You can specify coordinates for the menu to appear, and you can usually find these on the click event when you click an element.
44
+
45
+ The context menu is designed for you to manually handle the isOpen state in your application.
46
+
47
+ ```svelte
48
+ <ContextMenu>
49
+ <div class="section" style="white-space:pre-wrap;">
50
+ <strong>Brisbane</strong>
51
+ <small>BNE</small>
52
+ </div>
53
+ <hr />
54
+ <div class="section">Some notes about this seat</div>
55
+ <hr />
56
+
57
+ <label class="item">
58
+ <div class="section">
59
+ <input type="checkbox" /> An option
60
+ </div>
61
+ </label>
62
+
63
+ <hr />
64
+
65
+ <ul class="menu">
66
+ <li><button class="item">Item 1</button></li>
67
+ <li><button class="item">Item 2</button></li>
68
+ </ul>
69
+
70
+ <hr />
71
+
72
+ <ul class="menu menu--double">
73
+ <li><button class="item">Item 1</button></li>
74
+ <li><button class="item">Item 2</button></li>
75
+ </ul>
76
+ </ContextMenu>
77
+ ```
78
+
79
+ ## Modal
80
+
81
+ The modal component is useful for building more complex tools inside a builder.
82
+
83
+ You can provide your own footer elements to make either an okay/cancel alert, or next/next/done wizard style dialogue.
84
+
85
+ This uses the native dialogue element, so focus will always be inside the modal. Take care not to show more than one at a time.
86
+
87
+ ```svelte
88
+ {#snippet children()}
89
+ Hello this is the modal content
90
+ {/snippet}
91
+ {#snippet footerChildren()}
92
+ <button onclick={() => (isOpen = false)}>Ok!</button>
93
+ {/snippet}
94
+
95
+ <Modal title="Example modal" {children} {footerChildren} />
96
+ ```
97
+
98
+ ## Developing
99
+
100
+ Once you've nstalled dependencies with `npm install`, start a development storybook:
101
+
102
+ ```bash
103
+ npm run storybook
104
+ ```
105
+
106
+ Everything inside `src/lib` is part of the library, everything inside `src/routes` can be used as a showcase or preview app.
107
+
108
+ ## Building
109
+
110
+ To build the library:
111
+
112
+ ```bash
113
+ npm run package
114
+ ```
115
+
116
+ To create a production version of the showcase app:
117
+
118
+ ```bash
119
+ npm run build
120
+ ```
121
+
122
+ You can preview the production build with `npm run preview`.
123
+
124
+ > To deploy the app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for the target environment.
125
+
126
+ ## Publishing
127
+
128
+ Go into the `package.json` and give the package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
129
+
130
+ To publish the library to [npm](https://www.npmjs.com):
131
+
132
+ ```bash
133
+ npm publish
134
+ ```
@@ -0,0 +1,175 @@
1
+ <script lang="ts">
2
+ let { children } = $props();
3
+ </script>
4
+
5
+ <div class="builder-style-root">
6
+ {@render children?.()}
7
+ </div>
8
+
9
+ <style>
10
+ .builder-style-root {
11
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
12
+ line-height: 1.5;
13
+ font-weight: 400;
14
+
15
+ --text: #222;
16
+ --text-light: #888;
17
+ --background: #fff;
18
+ --border: rgba(122, 123, 135, 0.5);
19
+ --background-alt: #f2f4f5;
20
+
21
+ color: var(--text);
22
+ background-color: var(--background);
23
+
24
+ font-synthesis: none;
25
+ text-rendering: optimizeLegibility;
26
+ -webkit-font-smoothing: antialiased;
27
+ -moz-osx-font-smoothing: grayscale;
28
+ -webkit-text-size-adjust: 100%;
29
+
30
+ color-scheme: dark light;
31
+ :global(*) {
32
+ box-sizing: border-box;
33
+ }
34
+ }
35
+
36
+ @media (prefers-color-scheme: dark) {
37
+ .builder-style-root {
38
+ --text: #ccc;
39
+ --text-light: #888;
40
+ --background: #1a1a1a;
41
+ --background-alt: #2c2c2f;
42
+ --border: rgba(122, 123, 135, 0.5);
43
+ }
44
+ }
45
+
46
+ /* // builder-style-root */
47
+ .builder-style-root :global {
48
+ fieldset {
49
+ margin-bottom: 1rem;
50
+ padding: var(--padding);
51
+ border: 1px solid var(--border);
52
+ position: relative;
53
+ display: flex;
54
+ flex-direction: column;
55
+ gap: 0.5rem;
56
+ }
57
+
58
+ .fieldset {
59
+ padding: 0 var(--padding);
60
+ border: 1px solid transparent;
61
+ }
62
+ .fieldset,
63
+ fieldset {
64
+ --padding: 0.75rem;
65
+ margin-bottom: 1rem;
66
+ border-radius: 0.2rem;
67
+ }
68
+ fieldset.builder__spacious,
69
+ .fieldset.builder__spacious {
70
+ --padding: 1rem;
71
+ legend {
72
+ font-weight: bold;
73
+ }
74
+ }
75
+
76
+ .builder__inline {
77
+ display: flex;
78
+ flex-wrap: wrap;
79
+ gap: 0.5rem;
80
+ }
81
+
82
+ .buttons {
83
+ display: flex;
84
+ flex-wrap: wrap;
85
+ gap: 2px;
86
+ }
87
+
88
+ label {
89
+ margin-bottom: 0.5rem;
90
+ position: relative;
91
+ }
92
+ label span {
93
+ display: block;
94
+ margin-bottom: 0.3rem;
95
+ }
96
+
97
+ select,
98
+ button,
99
+ input,
100
+ textarea {
101
+ padding: 0.25rem 0.5rem;
102
+ background: var(--background);
103
+ border: 1px solid var(--border);
104
+ color: var(--text);
105
+ border-radius: 0.2rem;
106
+ }
107
+ select:not([multiple]),
108
+ button:not(:disabled) {
109
+ cursor: pointer;
110
+ &:hover,
111
+ &:focus-visible {
112
+ border-color: var(--text);
113
+ background: Highlight;
114
+ color: HighlightText;
115
+ }
116
+ }
117
+ button:disabled {
118
+ color: var(--text-light);
119
+ }
120
+
121
+ select,
122
+ input[type='text'],
123
+ input[type='password'],
124
+ textarea {
125
+ width: 100%;
126
+ }
127
+
128
+ .btn-icon {
129
+ padding: 0;
130
+ display: inline-flex;
131
+ height: 1.5rem;
132
+ width: 1.5rem;
133
+ justify-content: center;
134
+ align-items: center;
135
+ }
136
+
137
+ .builder__submit-row {
138
+ text-align: right;
139
+ border-top: 1px solid var(--border);
140
+ padding: 0.5rem 0;
141
+ }
142
+ hr {
143
+ width: 100%;
144
+ border: none;
145
+ border-bottom: 1px solid var(--border);
146
+ }
147
+
148
+ table.builder__table {
149
+ border-collapse: separate;
150
+ border: solid var(--border) 1px;
151
+ border-radius: 0.2rem;
152
+ border-spacing: 0;
153
+
154
+ td,
155
+ th {
156
+ border-left: solid var(--border) 1px;
157
+ border-top: solid var(--border) 1px;
158
+ padding: 0.25rem 0.5rem;
159
+ }
160
+
161
+ th {
162
+ background-color: var(--background-alt);
163
+ }
164
+
165
+ th {
166
+ border-top: none;
167
+ }
168
+
169
+ td:first-child,
170
+ th:first-child {
171
+ border-left: none;
172
+ }
173
+ }
174
+ }
175
+ </style>
@@ -0,0 +1,5 @@
1
+ declare const BuilderStyleRoot: import("svelte").Component<{
2
+ children: any;
3
+ }, {}, "">;
4
+ type BuilderStyleRoot = ReturnType<typeof BuilderStyleRoot>;
5
+ export default BuilderStyleRoot;
@@ -0,0 +1,66 @@
1
+ <script module>
2
+ import { defineMeta } from "@storybook/addon-svelte-csf";
3
+ import ContextMenu from "./ContextMenu.svelte";
4
+ import BuilderStyleRoot from "../BuilderStyleRoot/BuilderStyleRoot.svelte";
5
+
6
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
+ const { Story } = defineMeta({
8
+ title: "Example/ContextMenu",
9
+ component: ContextMenu,
10
+ tags: ["autodocs"],
11
+ argTypes: {},
12
+ args: {},
13
+ decorators: [() => BuilderStyleRoot],
14
+ });
15
+ </script>
16
+
17
+ {#snippet children()}
18
+ <div class="section" style="white-space:pre-wrap;">
19
+ <strong>Brisbane</strong>
20
+ <small style="opacity:0.5">BNE</small>
21
+ </div>
22
+ <hr />
23
+ <div class="section">Some notes about this seat</div>
24
+ <hr />
25
+
26
+ <label class="item">
27
+ <div class="section">
28
+ <input type="checkbox" /> An option
29
+ </div>
30
+ </label>
31
+
32
+ <label class="item">
33
+ <div class="section">
34
+ <input type="checkbox" /> Another option
35
+ </div>
36
+ </label>
37
+
38
+ <hr />
39
+
40
+ <ul class="menu">
41
+ <li><button class="item">Item 1</button></li>
42
+ <li><button class="item">Item 2</button></li>
43
+ <li><button class="item">Item 3</button></li>
44
+ </ul>
45
+
46
+ <hr />
47
+
48
+ <ul class="menu menu--double">
49
+ <li><button class="item">Item 1</button></li>
50
+ <li><button class="item">Item 2</button></li>
51
+ <li><button class="item">Item 3</button></li>
52
+ <li><button class="item">Item 4</button></li>
53
+ <li><button class="item">Item 5</button></li>
54
+ <li><button class="item">Item 6</button></li>
55
+ </ul>
56
+ {/snippet}
57
+
58
+ <!-- More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -->
59
+ <Story
60
+ name="Primary"
61
+ args={{
62
+ position: [0, 0],
63
+ children: children,
64
+ onClose: () => console.log("closed"),
65
+ }}
66
+ />
@@ -0,0 +1,27 @@
1
+ export default ContextMenu;
2
+ type ContextMenu = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const ContextMenu: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import ContextMenu from "./ContextMenu.svelte";
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }
@@ -0,0 +1,111 @@
1
+ <script lang="ts">
2
+ import { onMount } from "svelte";
3
+
4
+ let { position = [0, 0], children, onClose = () => {} } = $props();
5
+ let dialogEl = $state<HTMLDialogElement | undefined>();
6
+ let rect = $state<DOMRect>();
7
+ onMount(() => {
8
+ if (!dialogEl) {
9
+ // the dialog will always exist, but Typescript doesn't know that.
10
+ return;
11
+ }
12
+ dialogEl?.showModal();
13
+ rect = dialogEl.getBoundingClientRect();
14
+ return () => {
15
+ dialogEl?.close();
16
+ };
17
+ });
18
+
19
+ /* Proxy required otherwise Typescript complains */
20
+ function onCloseTypescriptProxy() {
21
+ onClose();
22
+ }
23
+ </script>
24
+
25
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
26
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
27
+ <dialog
28
+ class="dialog"
29
+ bind:this={dialogEl}
30
+ style:left={rect
31
+ ? (rect.width + position[0] > window.innerWidth
32
+ ? window.innerWidth - rect.width
33
+ : position[0]) + "px"
34
+ : ""}
35
+ style:top={rect
36
+ ? (rect.height + position[1] > window.innerHeight
37
+ ? window.innerHeight - rect.height - 10
38
+ : position[1]) + "px"
39
+ : ""}
40
+ onclick={onCloseTypescriptProxy}
41
+ onclose={onCloseTypescriptProxy}
42
+ >
43
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
44
+ <div onclick={(e) => e.stopPropagation()}>{@render children?.()}</div>
45
+ </dialog>
46
+
47
+ <style>
48
+ .dialog {
49
+ left: 0;
50
+ top: 0;
51
+ margin: 0;
52
+ padding: 0;
53
+ border: 1px solid rgba(0, 0, 0, 0.2);
54
+ border-radius: 0.5rem;
55
+ animation: fadein 0.2s;
56
+ &::backdrop {
57
+ animation: fadein 0.2s;
58
+ background: rgba(0, 0, 0, 0.05);
59
+ }
60
+ :global {
61
+ .menu {
62
+ list-style: none;
63
+ margin: 0;
64
+ padding: 0;
65
+ }
66
+ .menu--double {
67
+ display: grid;
68
+ grid-template-columns: 50% 50%;
69
+ gap: 0.25rem;
70
+ & li {
71
+ white-space: nowrap;
72
+ }
73
+ }
74
+ .section {
75
+ padding: 0.75rem;
76
+ }
77
+
78
+ .item,
79
+ button.item {
80
+ display: block;
81
+ width: 100%;
82
+ border: none;
83
+ background: none;
84
+ text-align: left;
85
+ cursor: pointer;
86
+ margin: 0 !important;
87
+ font-size: 1rem;
88
+ &:focus-visible,
89
+ &:hover {
90
+ background: Highlight;
91
+ color: HighlightText;
92
+ }
93
+ }
94
+ hr {
95
+ border: none;
96
+ margin: 0;
97
+ padding: 0;
98
+ border-bottom: 1px solid var(--border);
99
+ }
100
+ }
101
+ }
102
+
103
+ @keyframes fadein {
104
+ from {
105
+ opacity: 0;
106
+ }
107
+ to {
108
+ opacity: 1;
109
+ }
110
+ }
111
+ </style>
@@ -0,0 +1,7 @@
1
+ declare const ContextMenu: import("svelte").Component<{
2
+ position?: any[];
3
+ children: any;
4
+ onClose?: Function;
5
+ }, {}, "">;
6
+ type ContextMenu = ReturnType<typeof ContextMenu>;
7
+ export default ContextMenu;
@@ -0,0 +1,24 @@
1
+ <script module>
2
+ import { defineMeta } from "@storybook/addon-svelte-csf";
3
+ import GoogleDocScrollyteller from "./GoogleDocScrollyteller.svelte";
4
+ import BuilderStyleRoot from "../BuilderStyleRoot/BuilderStyleRoot.svelte";
5
+
6
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
+ const { Story } = defineMeta({
8
+ title: "Example/GoogleDocScrollyteller",
9
+ component: GoogleDocScrollyteller,
10
+ tags: ["autodocs"],
11
+ argTypes: {},
12
+ args: {},
13
+ decorators: [() => BuilderStyleRoot],
14
+ });
15
+ </script>
16
+
17
+ <!-- More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -->
18
+ <Story
19
+ name="Primary"
20
+ args={{
21
+ name: "myscrollyteller",
22
+ markerName: "mark",
23
+ }}
24
+ />
@@ -0,0 +1,27 @@
1
+ export default GoogleDocScrollyteller;
2
+ type GoogleDocScrollyteller = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const GoogleDocScrollyteller: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import GoogleDocScrollyteller from "./GoogleDocScrollyteller.svelte";
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }