@kws3/ui 1.6.5 → 1.6.9

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.
package/CHANGELOG.mdx ADDED
@@ -0,0 +1,85 @@
1
+
2
+ ## 1.6.9
3
+ - New `Timeline`, `TimelineItem` and `TimelineHeader` components.
4
+
5
+ ## 1.6.8
6
+ - Vertically align `is-icon` cells in `Grid`
7
+
8
+ ## 1.6.7
9
+ - Added granular events `showing`, `shown`, `hiding` and `hidden` for `Popover`.
10
+ - Added `is-checked` class on `Grid` when a row is checked using the multiselect checkboxes.
11
+ - New colors for `is-checked` class on `Grid`
12
+
13
+ ## 1.6.6
14
+ - Enhance `Popover` with native `show` `hide` `enable` `disable` methods
15
+
16
+ ## 1.6.5
17
+ - Filter fix on `DataSearch`
18
+
19
+ ## 1.6.4
20
+ - Add support for `dropdown_portal` prop in `SearchableSelect`
21
+
22
+ ## 1.6.3
23
+ - Prevent submit call on `MultiSelect` when `Enter` key is pressed while searching
24
+ - Fix filter items going blank after search is initiated in `DataSearch`
25
+
26
+ ## 1.6.2
27
+ - Add `dropdown_portal` prop on `MultiSelect` to allow rendering dropdown in alternative locations
28
+
29
+ ## 1.6.1
30
+ - New `Portal` component
31
+ - Use `Portal` for `MultiSelect` and `SearchableSelect` components
32
+
33
+ ## 1.6.0
34
+ - Fix `DataSearch` responsiveness for mobile
35
+ - Fix `Pagination` CSS for mobile
36
+ - Fix `DataSort` responsiveness for mobile
37
+ - Fix functionality of `DataSearch`
38
+
39
+ ## 1.5.9
40
+ - Fix `z-index` issue with `SearchableSelect`
41
+
42
+ ## 1.5.8
43
+ - Showing `undefined` on total in `Pagination`
44
+
45
+ ## 1.5.7
46
+ - Width calculation on `DataSearch`
47
+ - More `text` validation `Nl2br`
48
+
49
+ ## 1.5.6
50
+ - Fix attribute of `MultiSelect`
51
+ - Fix `text` checking on `Nl2br`
52
+
53
+ ## 1.5.5
54
+ - Added `BarChart`
55
+ - Added `LineChart`
56
+ - Added `AreaChart`
57
+ - Added `RadialChart`
58
+ - Support `sparklines` in `Charts`
59
+ - Add `yAxisOptions` and `horizontal` bar for `Charts`
60
+ - Fix attribute of `ConfirmButton`
61
+ - Fix error Handling in `MixedChart`
62
+
63
+ ## 1.5.1
64
+ - Chart bugfixes
65
+ - Fix attribute of `NumberInput` for UI testing
66
+
67
+ ## 1.5.0
68
+ - Added `DonutChart`
69
+ - Added `MixedChart`
70
+ - Added `PieChart`
71
+
72
+ ## 1.4.7
73
+ - Fix value mismatch on `NumberInput`
74
+
75
+ ## 1.4.6
76
+ - Fix Typing bug on `NumberInput`
77
+
78
+ ## 1.4.5
79
+ - Fix **on:change** event on `NumberInput`
80
+
81
+ ## 1.4.4
82
+ - import `Floatie`, `FloatingUIOutput`, `FloatiesStore` from `@kws3/ui` for `FloatingUIOutput`
83
+
84
+ ## 1.4.3
85
+ - Rename `completion_timeout` to `error_timeout` in `Buttons`
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 KWS3 Media Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  UI components for use with Svelte v3 applications.
2
2
 
3
- Docs: [https://ui.kws3.media](https://ui.kws3.media)
3
+ [Demo and Documentation](https://ui.kws3.media)
@@ -29,7 +29,8 @@
29
29
  <tr
30
30
  in:fly={{ x: 20, delay: 25 * row_index }}
31
31
  on:click|stopPropagation={rowClick}
32
- class:is-selected={rowActive}>
32
+ class:is-selected={rowActive}
33
+ class:is-checked={checked}>
33
34
  {#if bulk_actions}
34
35
  <td style="vertical-align:middle;">
35
36
  <Checkbox
@@ -55,7 +56,10 @@
55
56
  {/each}
56
57
  </tr>
57
58
  {:else}
58
- <tr on:click|stopPropagation={rowClick} class:is-selected={rowActive}>
59
+ <tr
60
+ on:click|stopPropagation={rowClick}
61
+ class:is-selected={rowActive}
62
+ class:is-checked={checked}>
59
63
  {#if bulk_actions}
60
64
  <td style="vertical-align:middle;">
61
65
  <Checkbox
@@ -7,11 +7,14 @@
7
7
  @param {''|'small'|'medium'|'large'} [icon_size="small"] - Size of the trigger icon displayed when default slot has no content, Default: `"small"`
8
8
  @param {string} [trigger="click"] - Determines the events that cause the Popover to show. Multiple event names are separated by spaces.
9
9
 
10
- **Examples:** `click`, `mouseenter`, `mouseenter focus`, Default: `"click"`
10
+ **Examples:** `click`, `mouseenter`, `mouseenter focus`
11
+
12
+ If you would like to trigger the popover programatically only, you can use `manual`., Default: `"click"`
11
13
  @param {string} [placement="auto"] - Preferred placement of the Popover
12
14
 
13
15
  Available options: <a target="_blank" href="https://atomiks.github.io/tippyjs/v6/all-props/#placement">https://atomiks.github.io/tippyjs/v6/all-props/#placement</a>, Default: `"auto"`
14
16
  @param {boolean} [interactive=false] - Allows you to interact with the Popover content, when turned on, Default: `false`
17
+ @param {boolean} [hide_on_click=true] - Whether the popover should hide on clicking outside of it, Default: `true`
15
18
  @param {object} [external_target=null] - Specify a target node reference to use as the Popover content
16
19
 
17
20
  When set to `null`, it will use the content of the `popover` slot, Default: `null`
@@ -20,6 +23,18 @@ When set to `null`, it will use the content of the `popover` slot, Default: `nul
20
23
  It can be any CSS value associated with `max-width` property, including `"none"`, Default: `"none"`
21
24
  @param {string} [style=""] - Inline CSS for Popover trigger, Default: `""`
22
25
  @param {string} [class=""] - CSS classes for Popover trigger, Default: `""`
26
+ @param {function} [open()] - Open function
27
+ @param {function} [close()] - Close function
28
+ @param {function} [enable()] - Enable function
29
+ @param {function} [disable()] - Disable function
30
+ @param {function} [setProps(props)] - SetProps function
31
+
32
+ ### Events
33
+ - `opening` - Triggered when popover is opening
34
+ - `open` - Triggered when popover is opened
35
+ - `closing` - Triggered when popover is closing
36
+ - `close` - Triggered when popover is closed
37
+ - `trigger` - Triggered when popover is triggered either programatically or by user interaction
23
38
 
24
39
  ### Slots
25
40
  - `<slot name="default" />` - Content of the Popover Trigger, by default it displays an Icon
@@ -28,11 +43,18 @@ It can be any CSS value associated with `max-width` property, including `"none"`
28
43
  -->
29
44
  <span
30
45
  use:popover={{ content: targetNode }}
46
+ bind:this={popoverParent}
47
+ on:showing={popoverShowing}
48
+ on:shown={popoverShown}
49
+ on:hiding={popoverHiding}
50
+ on:hidden={popoverHidden}
51
+ on:triggered={popoverTriggered}
31
52
  data-tippy-trigger={trigger}
32
53
  data-tippy-placement={placement}
33
54
  data-tippy-offset="[0, 10]"
34
55
  data-tippy-interactive={interactive ? "true" : "false"}
35
56
  data-tippy-maxWidth={max_width}
57
+ data-tippy-hideOnClick={hide_on_click ? "true" : "false"}
36
58
  style={_style}
37
59
  class={klass}>
38
60
  <!--Content of the Popover Trigger, by default it displays an Icon--><slot
@@ -51,8 +73,12 @@ It can be any CSS value associated with `max-width` property, including `"none"`
51
73
  </style>
52
74
 
53
75
  <script>
76
+ import { createEventDispatcher } from "svelte";
54
77
  import { popover } from "./Tooltip";
55
78
  import { Icon } from "@kws3/ui";
79
+
80
+ const fire = createEventDispatcher();
81
+
56
82
  /**
57
83
  * Icon used when default slot has no content
58
84
  */
@@ -71,6 +97,8 @@ It can be any CSS value associated with `max-width` property, including `"none"`
71
97
  * Determines the events that cause the Popover to show. Multiple event names are separated by spaces.
72
98
  *
73
99
  * **Examples:** `click`, `mouseenter`, `mouseenter focus`
100
+ *
101
+ * If you would like to trigger the popover programatically only, you can use `manual`.
74
102
  */
75
103
  export let trigger = "click";
76
104
  /**
@@ -83,6 +111,10 @@ It can be any CSS value associated with `max-width` property, including `"none"`
83
111
  * Allows you to interact with the Popover content, when turned on
84
112
  */
85
113
  export let interactive = false;
114
+ /**
115
+ * Whether the popover should hide on clicking outside of it
116
+ */
117
+ export let hide_on_click = true;
86
118
  /**
87
119
  * Specify a target node reference to use as the Popover content
88
120
  *
@@ -106,7 +138,66 @@ It can be any CSS value associated with `max-width` property, including `"none"`
106
138
  let klass = "";
107
139
  export { klass as class };
108
140
 
109
- let popoverNode;
141
+ let popoverNode, popoverParent;
142
+
143
+ const getInstance = () => {
144
+ return popoverParent._tippy;
145
+ };
146
+
147
+ export function open() {
148
+ getInstance().show();
149
+ }
150
+
151
+ export function close() {
152
+ getInstance().hide();
153
+ }
154
+
155
+ export function enable() {
156
+ getInstance().enable();
157
+ }
158
+
159
+ export function disable() {
160
+ getInstance().disable();
161
+ }
162
+
163
+ export function setProps(props) {
164
+ getInstance().setProps(props);
165
+ }
166
+
167
+ const popoverShowing = ({ detail }) => {
168
+ /**
169
+ * Triggered when popover is opening
170
+ */
171
+ fire("opening", detail);
172
+ };
173
+
174
+ const popoverShown = ({ detail }) => {
175
+ /**
176
+ * Triggered when popover is opened
177
+ */
178
+ fire("open", detail);
179
+ };
180
+
181
+ const popoverHiding = ({ detail }) => {
182
+ /**
183
+ * Triggered when popover is closing
184
+ */
185
+ fire("closing", detail);
186
+ };
187
+
188
+ const popoverHidden = ({ detail }) => {
189
+ /**
190
+ * Triggered when popover is closed
191
+ */
192
+ fire("close", detail);
193
+ };
194
+
195
+ const popoverTriggered = ({ detail }) => {
196
+ /**
197
+ * Triggered when popover is triggered either programatically or by user interaction
198
+ */
199
+ fire("trigger", detail);
200
+ };
110
201
 
111
202
  $: _style = `cursor:pointer;${style}`;
112
203
  $: targetNode = external_target ? external_target : popoverNode;
@@ -0,0 +1,28 @@
1
+ <!--
2
+ @component
3
+
4
+
5
+ @param {'left'|'center'|'right'} [align="left"] - Alignment of the Timeline child items, Default: `"left"`
6
+ @param {string} [class=""] - CSS classes for the Timeline container, Default: `""`
7
+
8
+ ### Slots
9
+ - `<slot name="default" />` - Default slot for placing all TimelineItem and TimelineHeader components
10
+
11
+ -->
12
+ <ul class="kws-timeline is-{align} {klass}">
13
+ <!--Default slot for placing all TimelineItem and TimelineHeader components--><slot />
14
+ </ul>
15
+
16
+ <script>
17
+ /**
18
+ * Alignment of the Timeline child items
19
+ * @type {'left'|'center'|'right'}
20
+ */
21
+ export let align = "left";
22
+
23
+ /**
24
+ * CSS classes for the Timeline container
25
+ */
26
+ let klass = "";
27
+ export { klass as class };
28
+ </script>
@@ -0,0 +1,21 @@
1
+ <!--
2
+ @component
3
+
4
+
5
+ @param {string} [class=""] - CSS classes for the TimelineItem container, Default: `""`
6
+
7
+ ### Slots
8
+ - `<slot name="default" />` - Content of the header, recommended to wrap with a `.tag` element.
9
+
10
+ -->
11
+ <header class="kws-timeline-header {klass}">
12
+ <!--Content of the header, recommended to wrap with a `.tag` element.--><slot />
13
+ </header>
14
+
15
+ <script>
16
+ /**
17
+ * CSS classes for the TimelineItem container
18
+ */
19
+ let klass = "";
20
+ export { klass as class };
21
+ </script>
@@ -0,0 +1,70 @@
1
+ <!--
2
+ @component
3
+
4
+
5
+ @param {''|'dark' | 'light' | 'warning' | 'info' | 'danger' | 'primary' | 'success'} [color="primary"] - Color of marker and border, Default: `"primary"`
6
+ @param {string} [marker_icon="null"] - Any icon name accepted by the Icon component, icon will be placed inside the marker, Default: `"null"`
7
+ @param {string} [marker_image="null"] - Any image URL, the image will be placed inside the marker, Default: `"null"`
8
+ @param {string} [class=""] - CSS classes for the TimelineItem container, Default: `""`
9
+
10
+ ### Slots
11
+ - `<slot name="above" />` - Optional text to be displayed above the main text
12
+ - `<slot name="default" />` - Default slot containing the main text
13
+ - `<slot name="below" />` - Optional text to be displayed below the main text
14
+ - `<slot name="thumbnail" />` - Optional thumbnail image do be displayed next to the main content
15
+
16
+ -->
17
+ <li class="kws-timeline-item is-{color} {klass}">
18
+ <div class="kws-timeline-marker">
19
+ {#if marker_icon && !marker_image}
20
+ <Icon icon={marker_icon} />
21
+ {/if}{#if marker_image && !marker_icon}
22
+ <figure class="image is-32x32"><img src={marker_image} alt="" /></figure>
23
+ {/if}
24
+ </div>
25
+ <div class="kws-timeline-content">
26
+ <span class="is-block has-text-grey"
27
+ ><!--Optional text to be displayed above the main text--><slot
28
+ name="above" /></span>
29
+ <span class="is-block description">
30
+ <!--Default slot containing the main text--><slot />
31
+ </span>
32
+
33
+ <span class="is-block has-text-grey">
34
+ <!--Optional text to be displayed below the main text--><slot
35
+ name="below" />
36
+ </span>
37
+ </div>
38
+ {#if $$slots.thumbnail}
39
+ <div class="kws-timeline-image">
40
+ <!--Optional thumbnail image do be displayed next to the main content--><slot
41
+ name="thumbnail" />
42
+ </div>
43
+ {/if}
44
+ </li>
45
+
46
+ <script>
47
+ import { Icon } from "@kws3/ui";
48
+
49
+ /**
50
+ * Color of marker and border
51
+ * @type {''|'dark' | 'light' | 'warning' | 'info' | 'danger' | 'primary' | 'success'}
52
+ */
53
+ export let color = "primary";
54
+ /**
55
+ * Any icon name accepted by the Icon component, icon will be placed inside the marker
56
+ * @type {string}
57
+ */
58
+ export let marker_icon = null;
59
+ /**
60
+ * Any image URL, the image will be placed inside the marker
61
+ * @type {string}
62
+ */
63
+ export let marker_image = null;
64
+
65
+ /**
66
+ * CSS classes for the TimelineItem container
67
+ */
68
+ let klass = "";
69
+ export { klass as class };
70
+ </script>
@@ -29,7 +29,23 @@ function createTippyAction(defaultOpts) {
29
29
  let instance;
30
30
 
31
31
  function makeOptions() {
32
- return Object.assign({}, defaultOpts, opts);
32
+ return Object.assign({}, defaultOpts, opts, {
33
+ onShow(instance) {
34
+ dispatch("showing", { instance });
35
+ },
36
+ onShown(instance) {
37
+ dispatch("shown", { instance });
38
+ },
39
+ onHide(instance) {
40
+ dispatch("hiding", { instance });
41
+ },
42
+ onHidden(instance) {
43
+ dispatch("hidden", { instance });
44
+ },
45
+ onTrigger(instance) {
46
+ dispatch("triggered", { instance });
47
+ },
48
+ });
33
49
  }
34
50
 
35
51
  function remakeInstance() {
@@ -51,6 +67,11 @@ function createTippyAction(defaultOpts) {
51
67
 
52
68
  makeInstance();
53
69
 
70
+ function dispatch(type, detail) {
71
+ const e = new CustomEvent(type, { bubbles: false, detail });
72
+ node.dispatchEvent(e);
73
+ }
74
+
54
75
  return {
55
76
  update(_opts) {
56
77
  opts = _opts;
package/index.js CHANGED
@@ -10,6 +10,9 @@ export { default as Panel } from "./helpers/Panel.svelte";
10
10
  export { default as Notification } from "./helpers/Notification.svelte";
11
11
  export { default as Loader } from "./helpers/Loader.svelte";
12
12
  export { default as ActionSheet } from "./helpers/ActionSheet.svelte";
13
+ export { default as Timeline } from "./helpers/Timeline/Timeline.svelte";
14
+ export { default as TimelineItem } from "./helpers/Timeline/TimelineItem.svelte";
15
+ export { default as TimelineHeader } from "./helpers/Timeline/TimelineHeader.svelte";
13
16
  export { default as Nl2br } from "./helpers/Nl2br.svelte";
14
17
  export { default as ClipboardCopier } from "./helpers/ClipboardCopier.svelte";
15
18
  export { alert, confirm, prompt, default as Dialog } from "./helpers/Dialog";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kws3/ui",
3
- "version": "1.6.5",
3
+ "version": "1.6.9",
4
4
  "description": "UI components for use with Svelte v3 applications.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -29,5 +29,5 @@
29
29
  "text-mask-core": "^5.1.2",
30
30
  "tippy.js": "^6.3.1"
31
31
  },
32
- "gitHead": "7bd56973e65c032a94e8285e321de06d0a89d051"
32
+ "gitHead": "85f8066201dc00eef8977c9a41239b377a5ca878"
33
33
  }
@@ -2,7 +2,7 @@
2
2
  @component
3
3
 
4
4
 
5
- @param {boolean} [active=false] - Used to set the active pane., Default: `false`
5
+ @param {boolean} [active=false] - Used to set the active pane, Default: `false`
6
6
  @param {string} [style=""] - Inline CSS of component, Default: `""`
7
7
  @param {boolean} [v_center=true] - Vertical alignment of content inside the active pane., Default: `true`
8
8
  @param {boolean} [h_center=true] - Horizontal alignment of content inside the active pane., Default: `true`
@@ -40,7 +40,7 @@ This will work only when `track_height` is set to `true`
40
40
  const fire = createEventDispatcher();
41
41
 
42
42
  /**
43
- * Used to set the active pane.
43
+ * Used to set the active pane
44
44
  */
45
45
  export let active = false,
46
46
  /**
@@ -10,26 +10,23 @@
10
10
  - `<slot name="default" />`
11
11
 
12
12
  -->
13
- <div
14
- class="sliding-pane-set {vertical ? 'is-vertical' : ''} {classes}"
15
- {style}>
13
+ <div class="sliding-pane-set {vertical ? 'is-vertical' : ''} {klass}" {style}>
16
14
  <slot />
17
15
  </div>
18
16
 
19
17
  <script>
20
18
  /**
21
- * Additional classes
22
- * @type {string}
19
+ * Inline style of component
23
20
  */
24
- export let classes = "",
21
+ export let style = "",
25
22
  /**
26
- * Inline style of component
27
- * @type {string}
28
- */
29
- style = "",
30
- /**
31
- * Vertical Aligned - true/false
32
- * @type {boolean}
23
+ * Vertical transform of SlidingPane.
33
24
  */
34
25
  vertical = false;
26
+
27
+ /**
28
+ * CSS classes for the SlidingPaneSet
29
+ */
30
+ let klass = "";
31
+ export { klass as class };
35
32
  </script>
package/styles/Grid.scss CHANGED
@@ -4,12 +4,14 @@ $kws-gridview-th-background: $table-background-color !default;
4
4
  $kws-gridview-th-color: $text !default;
5
5
  $kws-gridview-tag-margin: 0 0.125rem 0.125rem 0 !default;
6
6
  $kws-gridview-icon-size: 1.5em !default;
7
+ $kws-gridview-checked-row-background: $primary-light !default;
7
8
 
8
9
  .data-table .table {
9
10
  box-shadow: $kws-gridview-box-shadow;
10
11
  th {
11
12
  background: $kws-gridview-th-background;
12
13
  color: $kws-gridview-th-color;
14
+ vertical-align: middle;
13
15
  }
14
16
  &.is-bordered {
15
17
  tr {
@@ -34,6 +36,7 @@ $kws-gridview-icon-size: 1.5em !default;
34
36
  }
35
37
  td.is-icon {
36
38
  width: 25px;
39
+ vertical-align: middle;
37
40
  .icon {
38
41
  font-size: $kws-gridview-icon-size;
39
42
  }
@@ -43,4 +46,11 @@ $kws-gridview-icon-size: 1.5em !default;
43
46
  cursor: pointer;
44
47
  }
45
48
  }
49
+
50
+ tr.is-checked {
51
+ background-color: $kws-gridview-checked-row-background !important;
52
+ td {
53
+ background-color: $kws-gridview-checked-row-background !important;
54
+ }
55
+ }
46
56
  }
@@ -14,7 +14,7 @@ $kws-pagination-item-active-color: findColorInvert(
14
14
 
15
15
  $kws-pagination-frame-box-shadow: 0 0.125rem 0.1875rem rgba(0, 0, 0, 0.1),
16
16
  0 0 0 0.0625rem rgba(0, 0, 0, 0.1) !default;
17
- $kws-pagination-frame-background: linear-gradient(#fff, #fafafa);
17
+ $kws-pagination-frame-background: linear-gradient(#fff, #fafafa) !default;
18
18
 
19
19
  .pagination {
20
20
  &.is-small {
@@ -0,0 +1,164 @@
1
+ $kws-timeline-default-color: $grey !default;
2
+ $kws-timeline-default-color-invert: $light !default;
3
+
4
+ @mixin right-aligned-timeline-item {
5
+ flex-direction: row-reverse;
6
+ .kws-timeline-marker {
7
+ right: 0;
8
+ left: auto;
9
+ transform: translateX(50%);
10
+ }
11
+ .kws-timeline-content {
12
+ text-align: right;
13
+ padding-left: 0;
14
+ padding-right: 1.75rem;
15
+ }
16
+ &:before {
17
+ right: -0.5px;
18
+ left: auto;
19
+ }
20
+ }
21
+
22
+ .kws-timeline-item {
23
+ display: flex;
24
+ justify-content: center;
25
+ align-items: center;
26
+ position: relative;
27
+ padding: 0.5rem 0;
28
+ &:first-child {
29
+ padding-top: 0;
30
+ }
31
+ &:last-child {
32
+ padding-bottom: 0;
33
+ }
34
+ .kws-timeline-marker {
35
+ position: absolute;
36
+ left: 0;
37
+ background: $kws-timeline-default-color;
38
+ border: 1px solid $kws-timeline-default-color;
39
+ border-radius: 100%;
40
+ transform: translateX(-50%);
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ padding: 0.25rem;
45
+ overflow: hidden;
46
+ &:empty {
47
+ min-height: 1rem;
48
+ min-width: 1rem;
49
+ padding: 0;
50
+ border-width: 4px;
51
+ background: $kws-timeline-default-color-invert;
52
+ }
53
+ .icon {
54
+ color: $kws-timeline-default-color-invert;
55
+ width: 16px;
56
+ height: 16px;
57
+ font-size: 0.75rem !important;
58
+ }
59
+ .image {
60
+ margin: -0.25rem;
61
+ img {
62
+ border-radius: 100%;
63
+ }
64
+ }
65
+ }
66
+ .kws-timeline-content {
67
+ padding-left: 1.75rem;
68
+ flex-grow: 1;
69
+ flex-shrink: 1;
70
+ }
71
+ .kws-timeline-image {
72
+ flex-grow: 0;
73
+ flex-shrink: 0;
74
+ width: 32px;
75
+ img {
76
+ max-width: 100%;
77
+ max-height: 100%;
78
+ border-radius: $radius;
79
+ box-shadow: 0 0.125rem 0.1875rem rgba(10, 10, 10, 0.1),
80
+ 0 0 0 0.0625rem rgba(10, 10, 10, 0.1);
81
+ }
82
+ }
83
+
84
+ &:before {
85
+ content: "";
86
+ background-color: $kws-timeline-default-color;
87
+ display: block;
88
+ width: 1px;
89
+ height: 100%;
90
+ position: absolute;
91
+ left: -0.5px;
92
+ top: 0;
93
+ }
94
+
95
+ @each $name, $pair in $colors {
96
+ $color: nth($pair, 1);
97
+ $color-invert: nth($pair, 2);
98
+ &.is-#{$name} {
99
+ .kws-timeline-marker {
100
+ border-color: $color;
101
+ background-color: $color;
102
+ &:empty {
103
+ background-color: $color-invert;
104
+ }
105
+ .icon {
106
+ color: $color-invert;
107
+ }
108
+ }
109
+ &:before {
110
+ background-color: $color;
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ .kws-timeline-header {
117
+ width: 4em;
118
+ min-width: 4em;
119
+ word-wrap: normal;
120
+ text-align: center;
121
+ transform: translateX(-25px);
122
+ + .kws-timeline-header {
123
+ padding-top: 0.5rem;
124
+ }
125
+ }
126
+
127
+ .kws-timeline {
128
+ list-style: none;
129
+ margin: 0;
130
+ padding: 1rem;
131
+ display: flex;
132
+ flex-direction: column;
133
+
134
+ &.is-center {
135
+ .kws-timeline-item {
136
+ width: 50%;
137
+ align-self: flex-end;
138
+ flex-direction: row;
139
+ &:nth-of-type(2n) {
140
+ align-self: flex-start;
141
+ @include right-aligned-timeline-item;
142
+ }
143
+ }
144
+ .kws-timeline-header {
145
+ width: 100%;
146
+ transform: none;
147
+ }
148
+ }
149
+
150
+ &.is-right {
151
+ justify-content: flex-end;
152
+ align-items: flex-end;
153
+ .kws-timeline-item {
154
+ width: 100%;
155
+ align-self: flex-end;
156
+ @include right-aligned-timeline-item;
157
+ }
158
+ .kws-timeline-header {
159
+ transform: translateX(25px);
160
+ width: 100%;
161
+ text-align: right;
162
+ }
163
+ }
164
+ }