diff --git a/packages/docs/.vitepress/theme/data/sidebar.json b/packages/docs/.vitepress/theme/data/sidebar.json index 703c91b..b092261 100644 --- a/packages/docs/.vitepress/theme/data/sidebar.json +++ b/packages/docs/.vitepress/theme/data/sidebar.json @@ -62,7 +62,14 @@ { "text": "Store", "link": "/zero-core/modules/form/store" } ] }, - { "text": "Markdown Parser", "link": "/zero-core/modules/markdown-parser/components/zero-markdown-parser" }, + { + "text": "Markdown Parser", + "collapsed": true, + "items": [ + { "text": "Components", "link": "/zero-core/modules/markdown-parser/components" }, + { "text": "Composables", "link": "/zero-core/modules/markdown-parser/composables" } + ] + }, { "text": "Toaster", "collapsed": true, diff --git a/packages/docs/content/zero-core/modules/button/components.md b/packages/docs/content/zero-core/modules/button/components.md index 322f0a3..e511280 100644 --- a/packages/docs/content/zero-core/modules/button/components.md +++ b/packages/docs/content/zero-core/modules/button/components.md @@ -2,19 +2,55 @@ # Zero Button +A feature-rich button component. It can be used as an internal or external link, as a regular button or as a button with loading states. +If an ID is provided via the `id` prop, the button will be registered in the [zeroButtonStore](/zero-core/modules/button/store) with a tracking object that makes loading states available. ## Props | Prop | type | description | values | | ---- | ---- | ----------- | ------ | -| `tag`(optional) | string | | | -| `to`(optional) | string\|object | | | -| `target`(optional) | string\|object | | | -| `id`(optional) | string\|object | | | -| `forceDisabled`(optional) | boolean | | | -| `forceLoading`(optional) | boolean | | | -| `selected`(optional) | boolean | | | +| `tag`(optional) | string | Defines the type of component this button will use. Use `nuxt-link` to create an internal link, `a` for an external link and `button` for a regular button element. Alternatively, any valid html element tag can be provided. | `nuxt-link,a,button,etc.` | +| `to`(optional) | string\|object | If the button is intended to be used as either an internal or external link, this is the URL which it should navigate to. | | +| `target`(optional) | string\|object | The target attribute to add to the native anchor tag element. Mostly used for opening external links in new tabs with the target set to `_blank`. | | +| `id`(optional) | string\|object | A unique ID for this button. Only required if using the button with loading state functionality. | | +| `forceDisabled`(optional) | boolean | A boolean indicating if this button should be forced to be disabled. Otherwise the disabled state is automatically set to true when the button is loading; see the [loading](/zero-core/modules/button/components#loading) computed prop below. | | +| `forceLoading`(optional) | boolean | A boolean offering the ability to force a button's loading state. Will override the automatic loading state handling. | | +| `selected`(optional) | boolean | A boolean indicating if this button is set to a 'selected' state. This only toggles a `selected` class in the button's classlist which can be styled from components above using `:deep(.button)`. | | + +## Computed properties + +#### button() + + +Returns this button's tracking object from the [button store](/zero-core/modules/button/store#buttons). + + + - **returns:** `Object` + +#### loading() + + +Returns the loading state from the button tracking object above. Is overriden by the boolean value of the `forceLoading` prop. + + + - **returns:** `boolean` + +#### disabled() + + +Returns a boolean indicating if this button is disabled or not. Returns `true` if the button loading value is true as per above or if the `forceDisabled` prop is set to true. + + + - **returns:** `boolean` + +#### component() + + +The component name to be passed to the `:is` prop of the Nuxt [dynamic component](https://nuxt.com/docs/guide/directory-structure/components#dynamic-components) instance. If the button is disabled, the `button` tag is returned. + + + - **returns:** `string` ## Slots @@ -23,22 +59,30 @@ **name:** `default` **scoped:** `true` + +The button content. + | binding | type | description | | ------- | ---- | ----------- | -| `loading` | | | +| `loading` | `mixed` | Binds the loading state returned by the [loading](/zero-core/modules/button/components#loading) computed prop. | ## Emitters - - **clicked** - undefined + - **clicked** - Emits the click event received by the [clickHandler](/zero-core/modules/button/components#clickhandler) on click. ## Methods #### clickHandler() -Emits a 'clicked' event. If the button has an ID, the id will be used +Emits a 'clicked' event. If the button has an ID, the id will be used to set the loading state in the button store using [setButton](/zero-core/modules/button/store#setbutton). -to set the loading state in the button store using [setButton](/zero-core/modules/button/store.html#setbutton) +| param | type | description | +| ----- | ---- | ----------- | +| `e` | Object | A [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event) event. | #### handleSessionExpired() + + +If this button is loading, sets its loading state to `false` with [setButton](/zero-core/modules/button/store#setbutton). Before the button component is mounted, this method is registered with the Zero Core [$bus](/zero-core/plugins#bus) plugin listening for a `session-expired` event. It can be used for example, to set button loading states to false if a websocket disconnects. diff --git a/packages/docs/content/zero-core/modules/button/store.md b/packages/docs/content/zero-core/modules/button/store.md index 8b13789..76a64aa 100644 --- a/packages/docs/content/zero-core/modules/button/store.md +++ b/packages/docs/content/zero-core/modules/button/store.md @@ -1 +1,67 @@ +# useZeroButtonStore() + + +A store for tracking [button](/zero-core/modules/button/components) component loading states. + +## Data + + + - [buttons](#buttons) + +## Methods + + + - [setButton()](#setbutton) + - [removeButton()](#removebutton) + +## All Members + +#### buttons + + +**type:** `Object` + + +An object containing nested objects representing individual button instances. Each nested object exists at the root level of this object, has a key corresponding to its button ID and should be of the following structure: + +```js + +{ + + id: string, + + loading: boolean + +} + +``` + + +**Kind:** inner ref of [useZeroButtonStore](#usezerobuttonstore) + +#### setButton() + + +Sets a tracking object in the [buttons object](/zero-core/modules/button/store#buttons) to the incoming payload. The key used to reference this tracking object is the button ID. + + +**Kind:** inner method of [useZeroButtonStore](#usezerobuttonstore) + +| param | type | description | +| ----- | ---- | ----------- | +| `payload` | Object | The tracking object to add. | +| `payload.id` | string | The ID of the button to track. | +| `payload.loading` | boolean | A boolean indicating whether or not this button is loading. | + +#### removeButton() + + +Removes a tracking object from the [buttons object](/zero-core/modules/button/store#buttons). + + +**Kind:** inner method of [useZeroButtonStore](#usezerobuttonstore) + +| param | type | description | +| ----- | ---- | ----------- | +| `id` | string | The ID of the button to remove. | diff --git a/packages/docs/content/zero-core/modules/markdown-parser/components.md b/packages/docs/content/zero-core/modules/markdown-parser/components.md new file mode 100644 index 0000000..c7184a3 --- /dev/null +++ b/packages/docs/content/zero-core/modules/markdown-parser/components.md @@ -0,0 +1,38 @@ + +# Zero Markdown Parser + + +This component parses an input string returning HTML markup according to conventional markdown text-to-HTML conversion syntax. Uses [unified](https://github.com/unifiedjs/unified) in tandem with several [remark](https://github.com/remarkjs/remark) and [rehype](https://github.com/rehypejs/rehype/tree/main) plugins to transform the input string. + +While processing the markdown input string, copy buttons are attached to heading, code and pre elements with [useAddCopyButton](/zero-core/modules/markdown-parser/composables#useaddcopybutton). These elements are additionally processed with [useAddCssSelectors](/zero-core/modules/markdown-parser/composables#useaddcssselectors) and [useAddDataAttributes](/zero-core/modules/markdown-parser/composables#useadddataattributes). + +Once the output markup has been rendered using the component template, its inner HTML is parsed for all of the added copy buttons by searching for the `.copy-button` class. Event listeners are attached to copy buttons which, in the case of headings, copy the URL with the heading hash to the clipboard or, in the case of code blocks, copy the code content to the clipboard. + +## Props + +| Prop | type | description | values | +| ---- | ---- | ----------- | ------ | +| `markdown` | string | The input markdown string to process. | | +| `disableHeadingLinks`(optional) | boolean | A boolean indicating whether or not links should be attached to heading nodes. | | + +## Emitters + + + - **foundHeadingNodes** - Emits all HTML heading nodes parsed from the processed markdown output. + +## Methods + +#### initializeCopyButtons() + + +Parses processed HTML output for button elements with a class of either `.markdown` or `.copy-button`. A 'click' event listener is attached to each button that, depending on the type of node, either copies a URL + hash in the case of a heading or in the case of a code block, copies its content (found in the next sibling element relative to the button). In both cases, text is copied to the clipboard using [zeroAddTextToClipboard](/zero-core/composables/zero-add-text-to-clipboard). As part of the click handler attached to each button, a 'copied' state is added to its inner HTML with a feedback message indicating to the user if the text in question has been copied to the clipboard. Immediately before this, the [clearCopiedState](/zero-core/modules/markdown-parser/components#clearcopiedstates) method is called to reset all button 'copied' states. + +#### clearCopiedStates() + + +Loops through all copy buttons parsed from [initializeCopyButtons](/zero-core/modules/markdown-parser/components#initializecopybuttons) and resets 'copied' states. + +#### collectAndEmitHeadingNodes() + + +Finds all heading nodes (`h1`, `h2`, `h3`, etc.) in the processed markdown output and emits them using the [foundHeadingNodes](/zero-core/modules/markdown-parser/components/zero-markdown-parser#emitters) emitter. diff --git a/packages/docs/content/zero-core/modules/markdown-parser/components/zero-markdown-parser.md b/packages/docs/content/zero-core/modules/markdown-parser/components/zero-markdown-parser.md index cf8a512..f793a21 100644 --- a/packages/docs/content/zero-core/modules/markdown-parser/components/zero-markdown-parser.md +++ b/packages/docs/content/zero-core/modules/markdown-parser/components/zero-markdown-parser.md @@ -1,24 +1,35 @@ # Zero Markdown Parser +This component parses an input string returning HTML markup according to conventional markdown text-to-HTML conversion syntax. Uses [unified](https://github.com/unifiedjs/unified) in tandem with several [remark](https://github.com/remarkjs/remark) and [rehype](https://github.com/rehypejs/rehype/tree/main) plugins to transform the input string. +After the input text has been processed and rendered using the component template, its inner HTML is parsed for heading nodes as well as buttons with the `.copy-button` class. Links are attached to heading nodes that append their heading hash to the URL allowing for easy navigation to a specific section in a page. Event listeners are attached to copy buttons which copy either these heading links or the text in the next sibling node; for example, the contents of a code block. ## Props | Prop | type | description | values | | ---- | ---- | ----------- | ------ | -| `markdown` | string | | | -| `disableHeadingLinks`(optional) | boolean | | | +| `markdown` | string | The input markdown string to process. | | +| `disableHeadingLinks`(optional) | boolean | A boolean indicating whether or not links should be attached to heading nodes. | | ## Emitters - - **foundHeadingNodes** - undefined + - **foundHeadingNodes** - Emits all HTML heading nodes parsed from the processed markdown output. ## Methods #### initializeCopyButtons() + +Parses processed HTML output for elements with a class of either `.markdown` or `.copy-button`. A 'click' event listener is attached to each element that, depending on the type of node, either copies a URL + hash in the case of a heading or the next sibling's text content if otherwise. In both cases, text is copied to the clipboard using [zeroAddTextToClipboard](/zero-core/composables/zero-add-text-to-clipboard). As part of the click handler attached to each button, a 'copied' state is added to its inner HTML with a feedback message indicating to the user if the text in question has been copied to the clipboard. Immediately before this, the [clearCopiedState](/zero-core/modules/markdown-parser/components#clearcopiedstate) method is called to reset all button 'copied' states. + #### clearCopiedStates() + +Loops through all copy buttons parsed from [initializeCopyButtons](/zero-core/modules/markdown-parser/components#initializecopybuttons) and resets 'copied' states. + #### collectAndEmitHeadingNodes() + + +Finds all heading nodes (`h1`, `h2`, `h3`, etc.) in the processed markdown output and emits them using the [foundHeadingNodes](/zero-core/modules/markdown-parser/components/zero-markdown-parser#emitters) emitter. diff --git a/packages/docs/content/zero-core/modules/markdown-parser/composables.md b/packages/docs/content/zero-core/modules/markdown-parser/composables.md new file mode 100644 index 0000000..4eeefce --- /dev/null +++ b/packages/docs/content/zero-core/modules/markdown-parser/composables.md @@ -0,0 +1,85 @@ + +# useAddCopyButton() + + +Creates and appends a 'copy' button to an HTML element. The button is furnished with properties regarding the type of element it is to be appended to, a tooltip message and, in the case of heading nodes, a URL hash derived from the heading ID. + +## Methods + + + - [useAddCopyButton()](#useaddcopybutton) + +## All Members + +#### useAddCopyButton() + + + + + +**Kind:** inner method of [useAddCopyButton](#useaddcopybutton) + +| param | type | description | +| ----- | ---- | ----------- | +| `node` | HTMLElement | An HTML element to append a copy button to. | +| `id` | string | The element ID of the node if it is a heading node. | + + + - **Returns:** `HTMLElement` + +# useAddCssSelectors() + + +Adds classes to a provided HTML element. + +## Methods + + + - [useAddCssSelectors()](#useaddcssselectors) + +## All Members + +#### useAddCssSelectors() + + + + + +**Kind:** inner method of [useAddCssSelectors](#useaddcssselectors) + +| param | type | description | +| ----- | ---- | ----------- | +| `node` | HTMLElement | The HTML element to append classes to. | +| `id` | string | The ID of the element. | +| `classes` | string | The classes to add to append to the element's classlist. If multiple classes are to be added, they should be delimited by a space character. | + + + - **Returns:** `HTMLElement` + +# useAddDataAttributes() + + +Adds data attributes to an HTML element. + +## Methods + + + - [useAddDataAttributes()](#useadddataattributes) + +## All Members + +#### useAddDataAttributes() + + + + + +**Kind:** inner method of [useAddDataAttributes](#useadddataattributes) + +| param | type | description | +| ----- | ---- | ----------- | +| `node` | HTMLElement | The HTML element to add data attributes to. | +| `attrs` | Object | An object of key-value pairs to be assigned to element data attribute names and values respectively. | + + + - **Returns:** `HTMLElement` diff --git a/packages/docs/content/zero-core/modules/markdown-parser/composables/use-add-copy-button.md b/packages/docs/content/zero-core/modules/markdown-parser/composables/use-add-copy-button.md new file mode 100644 index 0000000..db5c5f7 --- /dev/null +++ b/packages/docs/content/zero-core/modules/markdown-parser/composables/use-add-copy-button.md @@ -0,0 +1,4 @@ +# useAddCopyButton() + + +Creates and appends a button to an HTML element. diff --git a/packages/docs/content/zero-core/modules/toaster/components.md b/packages/docs/content/zero-core/modules/toaster/components.md index 30a7ffe..7824fa3 100644 --- a/packages/docs/content/zero-core/modules/toaster/components.md +++ b/packages/docs/content/zero-core/modules/toaster/components.md @@ -2,13 +2,15 @@ # Zero Toast +A 'toast' component; a small window with a message for the user that pops up like toast out of a toaster. As soon as the component is mounted, the [unToast]() method is called which will automatically clear the toast after a set time interval. +Additionally, a watcher is set to watch the toast prop's `jingle` key. The jingle property is an integer value which represents the number of 'repeats' of the same message. If this value is greater than zero, the watcher will call the unToast method below and set a timeout to update the toast message jingle property to `0`. This functionality effectively extends the life of an existing toast message if that message is repeatedly added rather than creating multiple popup windows with the same message. ## Props | Prop | type | description | values | | ---- | ---- | ----------- | ------ | -| `toast` | object | | | +| `toast` | object | The toast object for this component instance that is held in the [toaster store](/zero-core/modules/toaster/store). | | ## Slots @@ -17,24 +19,32 @@ **name:** `toast` **scoped:** `true` + +The content of the toast window. + | binding | type | description | | ------- | ---- | ----------- | -| `toast` | | | +| `toast` | `mixed` | Binds the 'toast' prop object to the slot. | ## Methods #### unToast() + +Sets a timer with a setTimeout function. Once the timer interval has elapsed, removes the toast message from view using the toaster store's [removeMessage](/zero-core/modules/toaster/store#removemessage) method. The time interval can be set in the nuxt.config.js file under `zero.modules.toaster.timeout` or it is derived from the toast prop's `.timeout` key. + # Zero Toaster +The Zero Toaster is a component that displays important info/messages to the user in small alert windows called 'toasts'. The name is a reference the way that alert messages pop up like toast out of a toaster. This component, the 'toaster', renders the individual [toast](/zero-core/modules/toaster/components#zero-toast) components that display a message to the user and allows for multiple messages to be displayed at once. +Uses a Vue [transition-group](https://vuejs.org/guide/built-ins/transition-group) to animate toast component entry and exit. ## Props | Prop | type | description | values | | ---- | ---- | ----------- | ------ | -| `from`(optional) | string\|object | | | +| `from`(optional) | string | Defines the direction which 'toast' windows should enter from relative to the viewport. Overrides the module setting set in the `nuxt.config.js` under `zero.modules.toaster`. | `top,bottom` | ## Slots @@ -43,6 +53,9 @@ **name:** `toast` **scoped:** `true` + +The content of the toast window. + | binding | type | description | | ------- | ---- | ----------- | -| `toast` | | | +| `toast` | `mixed` | Binds the toast object that is bound to the child toast component slot. This will be the same object passed as the 'toast' prop to the [toast component](/zero-core/modules/toaster/components#zero-toast). | diff --git a/packages/docs/content/zero-core/modules/toaster/store.md b/packages/docs/content/zero-core/modules/toaster/store.md index 8b13789..17b919c 100644 --- a/packages/docs/content/zero-core/modules/toaster/store.md +++ b/packages/docs/content/zero-core/modules/toaster/store.md @@ -1 +1,86 @@ +# useZeroToasterStore() + + +A store for toast message data tracking. Allows 'toaster' messages to be conveniently added from anywhere within an app. + +## Data + + + - [toasts](#toasts) + +## Methods + + + - [addMessage()](#addmessage) + - [removeMessage()](#removemessage) + - [updateToast()](#updatetoast) + +## All Members + +#### toasts + + +**type:** `Array` + + +An array of toast message objects containing message data and data about how the message should be displayed by the [toast and toaster components](/zero-core/modules/toaster/components). Each message object has the following structure: + +```js + +{ + + text: string, // toast message + + id: string, // automatically generated using the zeroUuid composable + + jingle: number, // automatically added, see the toast component for more info + + timeout: number, // how long the message should display in milliseconds + + from: string // the direction the toast should appear from, 'top' or 'bottom' + +} + +``` + + +**Kind:** inner ref of [useZeroToasterStore](#usezerotoasterstore) + +#### addMessage() + + +Add a message to be displayed with a [toast component](/zero-core/modules/toaster/components#zero-toast). + + +**Kind:** inner method of [useZeroToasterStore](#usezerotoasterstore) + +| param | type | description | +| ----- | ---- | ----------- | +| `payload` | Object | An object containing the message to display. The object should at least have the following text property but can additionally have any of the properties outlines above in [toasts](/zero-core/modules/toaster/store#toasts). | +| `payload.text` | string | The message to display. | + +#### removeMessage() + + +Removes a toast message object from the [toasts](/zero-core/modules/toaster/store#toasts) array. + + +**Kind:** inner method of [useZeroToasterStore](#usezerotoasterstore) + +| param | type | description | +| ----- | ---- | ----------- | +| `id` | string | The ID of the toast to remove. | + +#### updateToast() + + +Updates a toast message object from the [toasts](/zero-core/modules/toaster/store#toasts) array. + + +**Kind:** inner method of [useZeroToasterStore](#usezerotoasterstore) + +| param | type | description | +| ----- | ---- | ----------- | +| `id` | string | The ID of the toast to update. | +| `payload` | Object | An object with properties and values to assign to the toast object in question. See [toasts](/zero-core/modules/toaster/store#toasts) for possible key-value pairs. | diff --git a/packages/docs/content/zero-core/modules/websocket/plugins.md b/packages/docs/content/zero-core/modules/websocket/plugins.md index 8b13789..16ca085 100644 --- a/packages/docs/content/zero-core/modules/websocket/plugins.md +++ b/packages/docs/content/zero-core/modules/websocket/plugins.md @@ -1 +1,22 @@ +# io + + +Provides a globally accessible 'io' object via [defineNuxtPlugin](https://nuxt.com/docs/migration/plugins-and-middleware#migration). This object contains the `connect` method below. + +## Methods + + + - [connect()](#connect) + +## All Members + +#### connect() + + +Initializes a web socket with socket.io-client's [io](https://socket.io/docs/v4/client-api) method and saves the newly created socket to the websocket store using [setWebsocketConnection](/zero-core/modules/websocket/store#setwebsocketstore). + +Right after creation, listeners for `connect` and `disconnect` events are added to the socket. The `connect` listener emits a `socket.io-connected` event to the global [$bus](/zero-core/plugins#bus) upon connecting and the `disconnect` listener attempts to reinitialize the connection on a 50ms interval. + + +**Kind:** inner method of [io](#io) diff --git a/packages/docs/content/zero-core/modules/websocket/store.md b/packages/docs/content/zero-core/modules/websocket/store.md index 8b13789..3d6e2c8 100644 --- a/packages/docs/content/zero-core/modules/websocket/store.md +++ b/packages/docs/content/zero-core/modules/websocket/store.md @@ -1 +1,40 @@ +# useZeroWebsocketStore() + + +A store for a client-side websocket to be used across an app. + +## Data + + + - [socket](#socket) + +## Methods + + + - [setWebsocketConnection()](#setwebsocketconnection) + +## All Members + +#### socket + + + + + +A websocket object. + + +**Kind:** inner ref of [useZeroWebsocketStore](#usezerowebsocketstore) + +#### setWebsocketConnection() + + +Sets the [socket](/zero-core/modules/websocket/store#socket) to the incoming payload. + + +**Kind:** inner method of [useZeroWebsocketStore](#usezerowebsocketstore) + +| param | type | description | +| ----- | ---- | ----------- | +| `payload` | Object | An initialized [websocket instance](https://socket.io/docs/v4/client-socket-instance/). | diff --git a/packages/docs/generate.js b/packages/docs/generate.js index 88bfee0..923639c 100644 --- a/packages/docs/generate.js +++ b/packages/docs/generate.js @@ -71,6 +71,14 @@ const concatenateList = [ dir: 'modules/form/stores', filename: 'store' }, + { + dir: 'modules/markdown-parser/components', + filename: 'components' + }, + { + dir: 'modules/markdown-parser/composables', + filename: 'composables' + }, { dir: 'modules/toaster/components', filename: 'components' diff --git a/packages/zero-core/modules/button/components/zero-button.vue b/packages/zero-core/modules/button/components/zero-button.vue index 7ea0133..513312f 100644 --- a/packages/zero-core/modules/button/components/zero-button.vue +++ b/packages/zero-core/modules/button/components/zero-button.vue @@ -7,45 +7,74 @@ :target="target" :class="['button', { selected }, { disabled }]" @click="clickHandler($event)"> - +