-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #116 from qld-gov-au/QOLOE-117-modal-component
QOLOE-117 Add modal component, bugfix for buttons, header
- Loading branch information
Showing
12 changed files
with
387 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
<!-- // QGDS Component: Button --> | ||
<!-- // https://getbootstrap.com/docs/5.3/components/buttons --> | ||
|
||
{{#unless islink}} | ||
<button class="btn {{variantClass}}" onclick="{{{onclick}}}" {{#if isdisabled}}disabled{{/if}}> | ||
{{#if iconClass}}<span class="btn-icon {{iconClass}}"></span>{{/if}}{{label}} | ||
<button class="btn {{variantClass}}" onclick="{{{onclick}}}" {{#if isdisabled}}disabled{{/if}} {{#if arialabel}}aria-label="{{arialabel}}"{{/if}} {{{dataatts}}}> | ||
{{#if iconClass}}<span class="btn-icon {{iconClass}}"></span>{{/if}}{{label}} | ||
</button> | ||
|
||
{{else}} | ||
<a class="btn {{variantClass}} {{#if isdisabled}}disabled" aria-disabled="true{{/if}}" href="{{href}}" target="{{target}}"> | ||
|
||
<a class="btn {{variantClass}} {{#if isdisabled}} disabled {{/if}}" {{#if isdisabled}} aria-disabled="true" {{/if}} href="{{href}}" target="{{target}}" {{#if arialabel}}aria-label="{{arialabel}}"{{/if}} {{{dataatts}}}> | ||
{{#if iconClass}}<span class="btn-icon {{iconClass}}"></span>{{/if}}{{label}} | ||
</a> | ||
{{/unless }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import Component from '../../../js/QGDSComponent.js' | ||
import template from "./modal.hbs?raw"; | ||
|
||
export class Modal { | ||
|
||
// Use the global Component class to create a new instance of the Modal component. | ||
// A data object, containing the Handlebars placeholder replacement strings, should be provided as an argument. | ||
|
||
constructor( data = {} ) { | ||
return new Component(template, data); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Canvas, Meta, Story, Source } from "@storybook/blocks" | ||
import * as ModalStories from "./modal.stories" | ||
|
||
import { Modal } from './Modal.js'; | ||
import defaultdata from './modal.data.json'; | ||
|
||
# Modal | ||
<Meta of={ModalStories} /> | ||
|
||
## Demo | ||
Please use the **Default story** to see the modal in action. | ||
|
||
## Example code | ||
<Source code={new Modal(defaultdata).html} language='jsx' dark={false}/> | ||
|
||
## Design resources | ||
- [Draft state (Figma)](https://www.figma.com/file/nMmoukrjPJ8qvUiwmuj1bs/forgov.qld.gov.au?type=design&node-id=1062-38211&mode=design&t=Mo0dPyJzGQ7YPs0s-0) | ||
- [Bootstrap] https://getbootstrap.com/docs/5.3/components/modal/ | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"modalSize": "modal-lg", | ||
"modalID": "terms-and-conditions", | ||
"header": { | ||
"title": "Terms and conditions", | ||
"closeButton": true | ||
}, | ||
"content": "<p>By signing in to this account, I agree to:</p><ul><li>Terms and conditions</li><li>Privacy policy</li><li>Cookie policy</li></ul>", | ||
"footer": { | ||
"buttons": [] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Extends Bootstraop 5.3 default modal behaviour | ||
*/ | ||
|
||
export function modal() { | ||
|
||
//Write custom modal functions here | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<!-- Example button to trigger the modal --> | ||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#{{modalID}}"> | ||
{{launchButtonLabel}} | ||
</button> | ||
|
||
<!-- You can also use a standard link. It must contain data-bs-toggle and data-bs-target attributes --> | ||
<p>You can also <a class="d-inline-block my-3" href="#" data-bs-toggle="modal" data-bs-target="#{{modalID}}">open a model</a> with a standard link. | ||
|
||
|
||
<!-- QGDS Modal --> | ||
<div class="modal fade" id="{{modalID}}" tabindex="-1" aria-labelledby="{{modalLabel}}" aria-hidden="true"> | ||
<div class="modal-dialog {{modalSize}}"> | ||
<div class="modal-content"> | ||
|
||
{{#if header}} | ||
<div class="modal-header"> | ||
<h1 class="modal-title" id="{{modalLabel}}">{{{ header.title }}}</h1> | ||
{{#if header.closeButton}} | ||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | ||
{{/if}} | ||
</div> | ||
{{/if}} | ||
|
||
<div class="modal-body"> | ||
{{{ content }}} | ||
</div> | ||
|
||
{{#if footer}} | ||
<div class="modal-footer"> | ||
{{#each footer.buttons}} | ||
{{{ . }}} | ||
{{/each}} | ||
</div> | ||
{{/if}} | ||
|
||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Modal extends https://getbootstrap.com/docs/5.3/components/modal/ | ||
// Default CSS variables https://getbootstrap.com/docs/5.3/components/modal/#variables | ||
|
||
// Default | ||
.modal { | ||
--#{$prefix}modal-zindex: #{$zindex-modal}; | ||
--#{$prefix}modal-width: #{$modal-md}; | ||
|
||
--#{$prefix}modal-margin: #{$modal-dialog-margin}; | ||
--#{$prefix}modal-color: #{$modal-content-color}; | ||
--#{$prefix}modal-bg: #{$modal-content-bg}; | ||
|
||
--#{$prefix}modal-border-color: var(--qld-light-grey); | ||
--#{$prefix}modal-border-width: 1px; | ||
--#{$prefix}modal-border-radius: 0.75rem; | ||
|
||
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs}; | ||
--#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius}; | ||
--#{$prefix}modal-header-padding: 2rem 1.5rem; | ||
|
||
--#{$prefix}modal-header-border-color: var(--qld-light-grey); | ||
--#{$prefix}modal-header-border-width: 1px; | ||
|
||
--#{$prefix}modal-title-line-height: 2rem; | ||
|
||
--#{$prefix}modal-footer-gap: 0; | ||
--#{$prefix}modal-footer-bg: none; | ||
--#{$prefix}modal-footer-border-color: none; | ||
--#{$prefix}modal-footer-border-width: none; | ||
|
||
//QGDS specific | ||
.btn-close { | ||
--qld-btn-close-icon: "data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M18.0547 18.5938C17.8203 18.8281 17.3906 18.8281 17.1562 18.5938L12 13.3984L6.80469 18.5938C6.57031 18.8281 6.14062 18.8281 5.90625 18.5938C5.67188 18.3594 5.67188 17.9297 5.90625 17.6953L11.1016 12.5L5.90625 7.34375C5.67188 7.10938 5.67188 6.67969 5.90625 6.44531C6.14062 6.21094 6.57031 6.21094 6.80469 6.44531L12 11.6406L17.1562 6.44531C17.3906 6.21094 17.8203 6.21094 18.0547 6.44531C18.2891 6.67969 18.2891 7.10938 18.0547 7.34375L12.8594 12.5L18.0547 17.6953C18.2891 17.9297 18.2891 18.3594 18.0547 18.5938Z' /%3E%3C/svg%3E%0A"; | ||
--qld-btn-close-color: var(--qld-light-action-secondary); | ||
--qld-btn-close-opacity: 1; | ||
--qld-btn-close-hover-opacity: 1; | ||
--qld-btn-close-focus-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25); | ||
|
||
background: var(--qld-btn-close-color); | ||
mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M18.0547 18.5938C17.8203 18.8281 17.3906 18.8281 17.1562 18.5938L12 13.3984L6.80469 18.5938C6.57031 18.8281 6.14062 18.8281 5.90625 18.5938C5.67188 18.3594 5.67188 17.9297 5.90625 17.6953L11.1016 12.5L5.90625 7.34375C5.67188 7.10938 5.67188 6.67969 5.90625 6.44531C6.14062 6.21094 6.57031 6.21094 6.80469 6.44531L12 11.6406L17.1562 6.44531C17.3906 6.21094 17.8203 6.21094 18.0547 6.44531C18.2891 6.67969 18.2891 7.10938 18.0547 7.34375L12.8594 12.5L18.0547 17.6953C18.2891 17.9297 18.2891 18.3594 18.0547 18.5938Z' /%3E%3C/svg%3E%0A"); | ||
mask-repeat: no-repeat; | ||
} | ||
|
||
.modal-header { | ||
padding: 2rem 1.5rem 1.5rem 1.5rem; | ||
|
||
.modal-title { | ||
line-height: var(--#{$prefix}modal-title-line-height); | ||
font-size: 1.5rem; | ||
} | ||
} | ||
|
||
.modal-body { | ||
padding: 1.5rem 1.5rem 2rem 1.5rem; | ||
} | ||
|
||
.modal-footer { | ||
padding: 0 1.5rem 2rem 1.5rem; | ||
display: flex; | ||
flex-direction: row; | ||
flex-wrap: nowrap; | ||
justify-content: flex-end; | ||
|
||
.btn { | ||
margin: 0 0 0 1.5rem; | ||
} | ||
} | ||
|
||
//Rescope for smaller modals | ||
.modal-dialog { | ||
&.modal-sm { | ||
.modal-footer { | ||
flex-direction: column-reverse; | ||
.btn { | ||
width: 100%; | ||
margin: 0 0 1.5rem 0; | ||
&:first-child { | ||
margin: 0; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
//Rescope for smaller viewports | ||
@include media-breakpoint-between(xs, sm) { | ||
.modal-footer { | ||
flex-direction: column-reverse; | ||
.btn { | ||
width: 100%; | ||
margin: 0 0 1.5rem 0; | ||
&:first-child { | ||
margin: 0; | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// modal.stories.js | ||
import { Modal } from './Modal.js'; | ||
import defaultdata from './modal.data.json'; | ||
|
||
//Load some buttons for modal footer | ||
import { Button } from '../button/Button.js'; | ||
|
||
let buttonItems = [{ | ||
"variantClass": "btn-tertiary", | ||
"islink": true, | ||
"isdisabled": false, | ||
"iconClass": "", | ||
"href": "https:///www.google.com", | ||
"label": "External link", | ||
"target": "_blank", | ||
"dataatts": false, | ||
"arialabel": false, | ||
},{ | ||
"variantClass": "btn-secondary", | ||
"islink": false, | ||
"isdisabled": false, | ||
"iconClass": "", | ||
"href": "#", | ||
"label": "Cancel", | ||
"target": "", | ||
"dataatts": "data-bs-dismiss='modal'", | ||
"arialabel": "Close", | ||
}, | ||
{ | ||
"variantClass": "btn-primary", | ||
"islink": false, | ||
"isdisabled": false, | ||
"iconClass": "", | ||
"href": "#", | ||
"label": "Confirm", | ||
"target": "", | ||
"dataatts": "data-bs-dismiss='modal'", | ||
"arialabel": "Close", | ||
}]; | ||
|
||
defaultdata.footer.buttons = buttonItems.map((item) => { | ||
return new Button(item).html; | ||
}); | ||
|
||
|
||
export default { | ||
tags: [''], | ||
title: 'Components/Modal', | ||
render: (args) => new Modal(args).html, | ||
|
||
argTypes: { | ||
buttons: { | ||
control: { disable: true }, | ||
}, | ||
modalSize: { | ||
name: "Size", | ||
description: `Set the size of the modal`, | ||
control: { | ||
type: "select", | ||
labels: { | ||
"modal-sm": "Small", | ||
"modal-default": "Default", | ||
"modal-lg": "Large", | ||
"modal-xl": "Extra Large", | ||
}, | ||
}, | ||
options: [ | ||
"modal-sm", | ||
"modal-default", | ||
"modal-lg", | ||
"modal-xl", | ||
], | ||
}, | ||
}, | ||
}; | ||
|
||
/** | ||
* Default Modal (Extra Large, 1140px) | ||
*/ | ||
export const Default = { | ||
args: { | ||
...defaultdata, | ||
modalID: 'modal-example-default', | ||
modalLabel: 'Default modal example', | ||
modalSize: 'modal-xl', | ||
launchButtonLabel: 'Open default modal', | ||
}, | ||
}; | ||
|
||
/** | ||
* Small Modal (575px) | ||
*/ | ||
|
||
export const SmallModal= { | ||
args: { | ||
...defaultdata, | ||
modalID: 'modal-example-small', | ||
modalLabel: 'Small modal example', | ||
modalSize: 'modal-sm', | ||
launchButtonLabel: 'Open small modal', | ||
}, | ||
}; | ||
|
||
|
||
/** | ||
* Large Modal (800px) | ||
*/ | ||
export const LargeModal = { | ||
args: { | ||
...defaultdata, | ||
modalID: 'modal-example-large', | ||
modalLabel: 'Large modal example', | ||
modalSize: 'modal-lg', | ||
launchButtonLabel: 'Open large modal', | ||
}, | ||
}; |
Oops, something went wrong.