├── src ├── resources │ ├── fonts │ │ ├── .gitkeep │ │ ├── SourceSansPro │ │ │ ├── SourceSansPro-Black.ttf │ │ │ ├── SourceSansPro-Bold.ttf │ │ │ ├── SourceSansPro-Light.ttf │ │ │ ├── SourceSansPro-Italic.ttf │ │ │ ├── SourceSansPro-Regular.ttf │ │ │ ├── SourceSansPro-SemiBold.ttf │ │ │ ├── SourceSansPro-BoldItalic.ttf │ │ │ ├── SourceSansPro-ExtraLight.ttf │ │ │ ├── SourceSansPro-BlackItalic.ttf │ │ │ ├── SourceSansPro-LightItalic.ttf │ │ │ ├── SourceSansPro-SemiBoldItalic.ttf │ │ │ └── SourceSansPro-ExtraLightItalic.ttf │ │ └── SourceSerifPro │ │ │ ├── SourceSerifPro-Black.ttf │ │ │ ├── SourceSerifPro-Bold.ttf │ │ │ ├── SourceSerifPro-Italic.ttf │ │ │ ├── SourceSerifPro-Light.ttf │ │ │ ├── SourceSerifPro-Regular.ttf │ │ │ ├── SourceSerifPro-SemiBold.ttf │ │ │ ├── SourceSerifPro-BlackItalic.ttf │ │ │ ├── SourceSerifPro-BoldItalic.ttf │ │ │ ├── SourceSerifPro-ExtraLight.ttf │ │ │ ├── SourceSerifPro-LightItalic.ttf │ │ │ ├── SourceSerifPro-ExtraLightItalic.ttf │ │ │ └── SourceSerifPro-SemiBoldItalic.ttf │ └── images │ │ ├── .gitkeep │ │ ├── favicon.png │ │ ├── busy-state.gif │ │ ├── Chevron-Left.svg │ │ ├── Chevron-Left-White.svg │ │ ├── Chevron-Right-White.svg │ │ ├── add-button-white.svg │ │ ├── add-button.svg │ │ ├── chevron-down.svg │ │ ├── Chevron-Right.svg │ │ ├── error.svg │ │ ├── remove-button.svg │ │ ├── long-description.svg │ │ ├── question.svg │ │ └── file-attach.svg ├── components │ ├── emailinput │ │ └── _emailinput.scss │ ├── numberinput │ │ └── _numberinput.scss │ ├── telephoneinput │ │ └── _telephoneinput.scss │ ├── text │ │ └── _text.scss │ ├── datepicker │ │ └── _datepicker.scss │ ├── title │ │ └── _title.scss │ ├── textinput │ │ └── _textinput.scss │ ├── footer │ │ └── _footer.scss │ ├── image │ │ └── _image.scss │ ├── tabsontop │ │ └── _tabsontop.scss │ ├── panelcontainer │ │ └── _panelcontainer.scss │ ├── checkboxgroup │ │ └── _checkboxgroup.scss │ ├── pageheader │ │ └── _pageheader.scss │ ├── dropdown │ │ └── _dropdown.scss │ ├── radiobutton │ │ └── _radiobutton.scss │ ├── button │ │ └── _button.scss │ ├── container │ │ └── _container.scss │ ├── wizard │ │ └── _wizard.scss │ ├── fileinput │ │ └── _fileinput.scss │ ├── verticaltabs │ │ └── _verticaltabs.scss │ └── accordion │ │ └── _accordion.scss ├── site │ ├── _base.scss │ ├── _variables.scss │ ├── _fonts.scss │ ├── _grid.scss │ └── _mixins.scss ├── theme.ts └── theme.scss ├── .parcelrc ├── env_template ├── post-css.js ├── LICENSE ├── clientlib-generator.js ├── .stylelintrc.json ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── workflows │ └── publish.yml ├── CODE_OF_CONDUCT.md └── CONTRIBUTING.md ├── .gitignore ├── .npmignore ├── package.json └── README.md /src/resources/fonts/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/resources/images/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/emailinput/_emailinput.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-emailinput{ 2 | @include input; 3 | } -------------------------------------------------------------------------------- /src/components/numberinput/_numberinput.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-numberinput{ 2 | @include input; 3 | } -------------------------------------------------------------------------------- /.parcelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@parcel/config-default", 3 | "namers": [ "parcel-namer-rewrite" ] 4 | } 5 | -------------------------------------------------------------------------------- /src/components/telephoneinput/_telephoneinput.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-telephoneinput{ 2 | @include input; 3 | } -------------------------------------------------------------------------------- /src/components/text/_text.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-text { 2 | color: $dark-gray; 3 | font-size: $font-m; 4 | } -------------------------------------------------------------------------------- /src/resources/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/images/favicon.png -------------------------------------------------------------------------------- /src/resources/images/busy-state.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/images/busy-state.gif -------------------------------------------------------------------------------- /src/components/datepicker/_datepicker.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-datepicker{ 2 | @include input; 3 | } 4 | .datepicker-calendar-icon{ 5 | top: 38px; 6 | } -------------------------------------------------------------------------------- /env_template: -------------------------------------------------------------------------------- 1 | # AEM url 2 | AEM_URL= 3 | 4 | # Adaptive form name 5 | AEM_ADAPTIVE_FORM=
6 | 7 | # AEM proxy port 8 | AEM_PROXY_PORT=7000 9 | -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-Black.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-Bold.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-Light.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-Italic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-SemiBold.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-Black.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-Bold.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-Italic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-Light.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-BoldItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-ExtraLight.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-Regular.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-SemiBold.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-BlackItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-LightItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-BlackItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-BoldItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-ExtraLight.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-LightItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSansPro/SourceSansPro-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSansPro/SourceSansPro-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /src/resources/fonts/SourceSerifPro/SourceSerifPro-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adobe/aem-forms-theme-easel/main/src/resources/fonts/SourceSerifPro/SourceSerifPro-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /src/components/title/_title.scss: -------------------------------------------------------------------------------- 1 | .cmp-title__text{ 2 | font-size: $font-xl; 3 | color: $dark-gray; 4 | font-weight: 500; 5 | letter-spacing: -1; 6 | line-height: 1.1; 7 | margin: $space-xl 0 $space-s 0; 8 | } -------------------------------------------------------------------------------- /src/components/textinput/_textinput.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-textinput { 2 | @include input; 3 | } 4 | 5 | textarea.cmp-adaptiveform-textinput__widget { 6 | @include widget; 7 | height: 80px; 8 | padding-top: $space-xs; 9 | } -------------------------------------------------------------------------------- /src/components/footer/_footer.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-footer { 2 | color: $dark-gray; 3 | background-color: $background-color; 4 | font-size: $font-s; 5 | min-height: 80px; 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | 10 | &__text { 11 | padding: $space-s; 12 | } 13 | } -------------------------------------------------------------------------------- /src/components/image/_image.scss: -------------------------------------------------------------------------------- 1 | /* ===============Imaget================== */ 2 | .cmp-image { 3 | border: 1px solid $very-light-gray; 4 | border-radius: 8px; 5 | 6 | &__image { 7 | border-radius: 8px; 8 | display: block; 9 | height: auto; 10 | max-width: 100%; 11 | width: inherit; 12 | margin: 0; 13 | padding: 0; 14 | } 15 | } -------------------------------------------------------------------------------- /src/components/tabsontop/_tabsontop.scss: -------------------------------------------------------------------------------- 1 | .cmp-tabs { 2 | @include container; 3 | 4 | &__label-container { 5 | margin-bottom: $space-s; 6 | } 7 | 8 | &__label { 9 | @include panel-label; 10 | } 11 | 12 | @include description; 13 | 14 | & &__tablist { 15 | @include tab-list; 16 | } 17 | 18 | &__tablist &__tab { 19 | @include tab; 20 | } 21 | 22 | &__tabpanel { 23 | @include tab-panel; 24 | } 25 | } -------------------------------------------------------------------------------- /post-css.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var postcss = require('postcss') 3 | var minmax = require('postcss-media-minmax') 4 | var themeCss = 'dist/theme.css' 5 | 6 | 7 | fs.readFile(themeCss, 'utf8', function (err,data) { 8 | if (err) { 9 | return console.log(err); 10 | } 11 | var output = postcss() 12 | .use(minmax()) 13 | .process(data) 14 | .css 15 | 16 | fs.writeFile(themeCss, output, 'utf8', function (err) { 17 | if (err) return console.log(err); 18 | }); 19 | }); -------------------------------------------------------------------------------- /src/site/_base.scss: -------------------------------------------------------------------------------- 1 | //== Defaults 2 | html, 3 | html body { 4 | color: $dark-gray; 5 | font-size: $font-m; 6 | background-color: white; 7 | font-family: defaultFont, "Helvetica Neue", Helvetica, Arial, sans-serif; 8 | 9 | } 10 | 11 | *,*:before,*:after { 12 | box-sizing: inherit; 13 | } 14 | 15 | .aem-Grid { 16 | @include generate-grid(default, $max_col); 17 | } 18 | 19 | // Phone breakpoint 20 | @media (max-width: 768px) { 21 | .aem-Grid { 22 | @include generate-grid(phone, $max_col); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/components/panelcontainer/_panelcontainer.scss: -------------------------------------------------------------------------------- 1 | /* ===============Panel Container================== */ 2 | .cmp-container { 3 | position: relative; 4 | display: flex; 5 | flex-direction: column; 6 | 7 | &[data-cmp-is="adaptiveFormPanel"] { 8 | margin: 0 0 $space-l 0; 9 | } 10 | 11 | &__label-container { 12 | margin-bottom: $space-s; 13 | } 14 | 15 | &__label { 16 | @include panel-label; 17 | } 18 | 19 | @include description; 20 | } 21 | 22 | .panelcontainer:last-child>[data-cmp-is="adaptiveFormPanel"] { 23 | margin-bottom: 0; 24 | } -------------------------------------------------------------------------------- /src/components/checkboxgroup/_checkboxgroup.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-checkboxgroup { 2 | @include container; 3 | 4 | &__label { 5 | @include label; 6 | } 7 | 8 | &__widget { 9 | @include list-container; 10 | } 11 | 12 | @include description; 13 | 14 | &__errormessage { 15 | @include error-message 16 | } 17 | 18 | &-item { 19 | @include list-item; 20 | } 21 | 22 | &-item &__label,&__option-label { 23 | @include checkbox-label; 24 | } 25 | 26 | &__option__widget { 27 | height: 1rem; 28 | width: 1rem; 29 | cursor: pointer; 30 | outline: none; 31 | } 32 | } -------------------------------------------------------------------------------- /src/resources/images/Chevron-Left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/pageheader/_pageheader.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-pageheader { 2 | display: flex; 3 | width: 100%; 4 | align-items: center; 5 | min-height: 80px; 6 | column-gap: $space-s; 7 | padding: 24px; 8 | color: $dark-gray; 9 | font-size: $font-m; 10 | border-radius: 0; 11 | word-break: break-all; 12 | box-sizing: border-box; 13 | 14 | img { 15 | height: $tap-height; 16 | margin: 0; 17 | width: auto; 18 | color: white; 19 | display: block; 20 | } 21 | 22 | div:last-child { 23 | display: flex; 24 | align-items: center; 25 | } 26 | 27 | p { 28 | margin: 0; 29 | } 30 | } -------------------------------------------------------------------------------- /src/resources/images/Chevron-Left-White.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/images/Chevron-Right-White.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/images/add-button-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/images/add-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/images/chevron-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/images/Chevron-Right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/dropdown/_dropdown.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-dropdown { 2 | @include input; 3 | 4 | &__widget { 5 | @include widget; 6 | appearance: none; 7 | cursor: pointer; 8 | background: url(./resources/images/chevron-down.svg); 9 | background-repeat: no-repeat; 10 | background-position: right 10px center; 11 | } 12 | [dir='rtl'] &__widget { 13 | background-position: left 10px center; 14 | } 15 | } 16 | 17 | select::after { 18 | content: ''; 19 | background: url(./resources/images/chevron-down.svg) center center / cover no-repeat; 20 | position: relative; 21 | } 22 | 23 | .cmp-adaptiveform-dropdown__widget[multiple='multiple'] { 24 | height: 80px; 25 | } -------------------------------------------------------------------------------- /src/components/radiobutton/_radiobutton.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-radiobutton { 2 | @include container; 3 | 4 | &__label { 5 | @include label; 6 | } 7 | 8 | &__widget { 9 | @include list-container; 10 | } 11 | 12 | @include description; 13 | 14 | &__errormessage { 15 | @include error-message; 16 | } 17 | 18 | &__option { 19 | @include list-item; 20 | &-label { 21 | display: flex; 22 | column-gap: $space-s; 23 | align-items: center; 24 | width: 100%; 25 | } 26 | } 27 | 28 | &__option__widget { 29 | height: 1.2rem; 30 | width: 1.2rem; 31 | cursor: pointer; 32 | outline: none; 33 | } 34 | 35 | span { 36 | opacity: 1; 37 | } 38 | } -------------------------------------------------------------------------------- /src/components/button/_button.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-button { 2 | position: relative; 3 | border: none; 4 | margin: $space-s 0; 5 | @include container; 6 | 7 | &__widget { 8 | @include primary-button; 9 | } 10 | 11 | @include description; 12 | &__shortdescription, &__longdescription{ 13 | margin-top: 8px; 14 | } 15 | &__questionmark{ 16 | @media (max-width: 640px) { 17 | top: -20px; 18 | } 19 | } 20 | @media (max-width: 640px) { 21 | margin-top: 32px; 22 | } 23 | } 24 | 25 | .submit { 26 | position: sticky; 27 | border-radius: 0; 28 | background: linear-gradient(to top, rgba(255, 255, 255, 1) 75%, rgba(255, 255, 255, 0) 100%); 29 | width: 100%; 30 | padding: $space-m 0; 31 | bottom: 0; 32 | left: 0; 33 | z-index: 12; 34 | } -------------------------------------------------------------------------------- /src/components/container/_container.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-container { 2 | &__wrapper { 3 | margin: 0 auto; 4 | padding: 0 $space-m; 5 | box-sizing: border-box; 6 | width: 100%; 7 | label > p:first-child, span > p:first-child { 8 | display: inline; 9 | } 10 | padding: $space-s; 11 | padding-inline: 20%; 12 | @media(max-width: 768px) { 13 | padding-inline: $space-s; 14 | } 15 | } 16 | 17 | &--loading { 18 | background: rgb(255, 255, 255) url(./resources/images/busy-state.gif) no-repeat fixed center; 19 | position: fixed; 20 | pointer-events: none; 21 | left: 0; 22 | right: 0; 23 | top: 0; 24 | bottom: 0; 25 | width: 100%; 26 | height: 100%; 27 | cursor: wait; 28 | z-index: 100000; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/resources/images/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/images/remove-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/images/long-description.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/images/question.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/images/file-attach.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Adobe, Inc. 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. 22 | -------------------------------------------------------------------------------- /src/components/wizard/_wizard.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-wizard { 2 | @include container; 3 | 4 | &__label-container { 5 | margin-bottom: $space-s; 6 | } 7 | 8 | &__label { 9 | @include panel-label; 10 | } 11 | 12 | @include description; 13 | 14 | &__tabs-container { 15 | max-width: 100%; 16 | overflow: auto; 17 | scrollbar-width: none; 18 | } 19 | 20 | &__tabList { 21 | @include tab-list; 22 | } 23 | 24 | &__tab { 25 | @include wizard-tab; 26 | 27 | // &--active~.cmp-adaptiveform-wizard__tab { 28 | // color: $gray; 29 | 30 | // &::before { 31 | // color: $dark-gray; 32 | // } 33 | // } 34 | } 35 | 36 | &__wizardpanel { 37 | @include tab-panel; 38 | } 39 | 40 | &__previousNav { 41 | @include wizard-previous-button; 42 | } 43 | 44 | &__nextNav { 45 | @include wizard-next-button; 46 | } 47 | &__containerNav { 48 | display: flex; 49 | justify-content: end; 50 | gap: 20px; 51 | position: absolute; 52 | width: 100%; 53 | bottom: -80px; 54 | } 55 | 56 | &__nav { 57 | &--previous { 58 | @include wizard-previous-button; 59 | 60 | } 61 | &--next { 62 | @include wizard-next-button; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/site/_variables.scss: -------------------------------------------------------------------------------- 1 | //== Font 2 | 3 | $font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; 4 | $font-family-title: 'Source Serif Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | 6 | 7 | // ====== font size====== 8 | $font-xl: 40px; 9 | $font-l: 24px; 10 | $font-m: 16px; 11 | $font-s: 12px; 12 | 13 | // ====== colors====== 14 | $dark-gray: rgb(22, 22, 22); 15 | $gray: rgb(109, 109, 109); 16 | $light-gray: #969696; 17 | $very-light-gray: #ddd; 18 | $background-color: #eee; 19 | $white: #fff; 20 | $error: #c61d17; 21 | $light-error: rgba(235, 60, 54, 0.05); 22 | $primary: $dark-gray; 23 | $dark-primary: $dark-gray; 24 | $disabled-color: $background-color; 25 | 26 | $focus-outline: 2px $primary solid; 27 | $error-outline: 2px $error solid; 28 | $border-light: 2px $background-color solid; 29 | $border-error: 2px $error solid; 30 | $border-dark: 2px $light-gray solid; 31 | $border-darker: 2px $gray solid; 32 | 33 | 34 | 35 | // ====== space ====== 36 | $space-xs: 4px; 37 | $space-s: 12px; 38 | $space-m: 36px; 39 | $space-l: 72px; 40 | $space-xl: 144px; 41 | 42 | $field-radius: 6px; 43 | $button-radius: 6px; 44 | $tap-height: 48px; 45 | $field-height: 48px; 46 | 47 | $font-weight-semi-bold: 600; 48 | 49 | 50 | //== Grid 51 | 52 | $max_col: 12; -------------------------------------------------------------------------------- /src/components/fileinput/_fileinput.scss: -------------------------------------------------------------------------------- 1 | .cmp-adaptiveform-fileinput { 2 | @include input; 3 | 4 | &__widgetlabel { 5 | &::before { 6 | content: ''; 7 | display: block; 8 | width: 16px; 9 | height: 16px; 10 | background: url(./resources/images/file-attach.svg) center center / cover no-repeat; 11 | } 12 | } 13 | 14 | &__widgetlabel { 15 | @include secondary-button; 16 | margin: $space-xs 0; 17 | display: flex; 18 | column-gap: $space-xs; 19 | align-items: center; 20 | pointer-events: all; 21 | } 22 | 23 | &__filelist { 24 | padding: 0; 25 | @include list-container; 26 | } 27 | 28 | &__fileitem { 29 | @include list-item; 30 | justify-content: space-between; 31 | width: 100%; 32 | } 33 | 34 | &__fileendcontainer { 35 | display: flex; 36 | justify-content: space-between; 37 | gap: $space-s; 38 | align-items: center; 39 | } 40 | 41 | &__filename { 42 | position: static; 43 | } 44 | 45 | input[type="file"] { 46 | column-gap: $space-l; 47 | } 48 | 49 | &__filedelete { 50 | float: right; 51 | font-size: $font-m; 52 | text-transform: uppercase; 53 | line-height: 1; 54 | font-weight: 500; 55 | color: $error; 56 | cursor: pointer; 57 | } 58 | 59 | br { 60 | display: none; 61 | } 62 | } -------------------------------------------------------------------------------- /src/theme.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * MIT License 4 | * 5 | * © Copyright 2022 Adobe. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | 27 | // Stylesheets 28 | import "./theme.scss"; 29 | import "./resources/images/favicon.png" 30 | -------------------------------------------------------------------------------- /src/theme.scss: -------------------------------------------------------------------------------- 1 | //== Variables 2 | @import 'site/variables'; 3 | @import 'site/_mixins'; 4 | 5 | //== fonts 6 | @import 'site/fonts'; 7 | 8 | 9 | //== base 10 | @import 'site/_grid.scss'; 11 | @import 'site/_base'; 12 | 13 | //== Core components 14 | @import './components/button/_button.scss'; 15 | @import './components/checkboxgroup/_checkboxgroup.scss'; 16 | @import './components/container/_container.scss'; 17 | @import './components/datepicker/_datepicker.scss'; 18 | @import './components/dropdown/_dropdown.scss'; 19 | @import './components/fileinput/_fileinput.scss'; 20 | @import './components/footer/_footer.scss'; 21 | @import './components/image/_image.scss'; 22 | @import './components/numberinput/_numberinput.scss'; 23 | @import './components/panelcontainer/_panelcontainer.scss'; 24 | @import './components/radiobutton/_radiobutton.scss'; 25 | @import './components/text/_text.scss'; 26 | @import './components/textinput/_textinput.scss'; 27 | @import './components/accordion/_accordion.scss'; 28 | @import './components/tabsontop/_tabsontop.scss'; 29 | @import './components/pageheader/_pageheader.scss'; 30 | @import './components/wizard/_wizard.scss'; 31 | @import './components/title/_title.scss'; 32 | @import './components/telephoneinput/_telephoneinput.scss'; 33 | @import './components/emailinput/_emailinput.scss'; 34 | @import './components/verticaltabs/_verticaltabs.scss'; 35 | -------------------------------------------------------------------------------- /clientlib-generator.js: -------------------------------------------------------------------------------- 1 | var clientlib = require("aem-clientlib-generator"); 2 | var path = require("path"); 3 | var process = require("process"); 4 | 5 | 6 | const CLIENTLIB_DIR = process.env.npm_config_directory || "theme-clientlibs" 7 | const CLIENTLIB_CATEGORY = process.env.npm_config_category 8 | 9 | if(!CLIENTLIB_CATEGORY){ 10 | throw 'category parameter should be present' 11 | } 12 | clientlib( 13 | [ 14 | { 15 | categories: [CLIENTLIB_CATEGORY], 16 | name: CLIENTLIB_CATEGORY, 17 | cssProcessor: ["default:none", "min:none"], 18 | jsProcessor: ["default:none", "min:gcc;compilationLevel=whitespace"], 19 | allowProxy: true, 20 | customProperties: [ 21 | "formsTheme" 22 | ], 23 | formsTheme: "true", 24 | serializationFormat: "xml", 25 | assets: { 26 | resources: { 27 | base: "css/resources/images", 28 | files: ["dist/**/*.svg", "dist/**/*.gif", "dist/**/*.png"] 29 | }, 30 | js: [ 31 | { src: "dist/theme.js", dest: "theme.js" }, 32 | { 33 | src: "dist/theme.js.map", 34 | dest: "theme.js.map", 35 | }, 36 | ], 37 | css: ["dist/theme.css", "dist/theme.css.map"], 38 | }, 39 | } 40 | ], 41 | { 42 | cwd: __dirname, 43 | clientLibRoot: path.join(__dirname, CLIENTLIB_DIR), 44 | }, 45 | function () { 46 | console.log("clientlibs created"); 47 | } 48 | ); -------------------------------------------------------------------------------- /src/components/verticaltabs/_verticaltabs.scss: -------------------------------------------------------------------------------- 1 | .cmp-verticaltabs{ 2 | font-size: $font-m; 3 | margin: $space-s; 4 | position: relative; 5 | 6 | &__tabs-container{ 7 | display: flex; 8 | margin-top: 16px; 9 | @media(max-width: 768px) { 10 | flex-direction: column; 11 | } 12 | } 13 | 14 | &__label-container { 15 | margin-bottom: $space-s; 16 | } 17 | 18 | &__label { 19 | @include panel-label; 20 | } 21 | 22 | &__tabpanel{ 23 | @include panel-label; 24 | flex:1; 25 | } 26 | 27 | &__tablist{ 28 | 29 | 30 | @media(min-width: 768px) { 31 | width: 150px; 32 | list-style: none; 33 | padding: 0; 34 | margin: 0; 35 | margin-inline-end: $space-m; 36 | } 37 | @media(max-width: 768px) { 38 | @include tab-list; 39 | padding-bottom: 2 * $space-xs; 40 | 41 | } 42 | } 43 | &__tab { 44 | cursor: pointer; 45 | @media(min-width: 768px) { 46 | padding-inline: 12px 4px; 47 | padding-block: 12px; 48 | margin-top: 8px; 49 | color: $gray; 50 | &:hover { 51 | border-inline-start: 2px solid $light-gray; 52 | } 53 | &--active { 54 | border-inline-start: 2px solid; 55 | color: $primary; 56 | &:hover{ 57 | border-inline-start: 2px solid $primary; 58 | } 59 | } 60 | } 61 | @media(max-width: 768px) { 62 | @include tab; 63 | } 64 | } 65 | 66 | @include description 67 | } -------------------------------------------------------------------------------- /src/components/accordion/_accordion.scss: -------------------------------------------------------------------------------- 1 | .cmp-accordion { 2 | @include container; 3 | @include description; 4 | 5 | &__item { 6 | opacity: 1; 7 | } 8 | 9 | &__header { 10 | padding: 0 $space-s; 11 | display: flex; 12 | } 13 | 14 | &__label-container { 15 | margin-bottom: $space-s; 16 | } 17 | 18 | &__label { 19 | @include panel-label; 20 | } 21 | 22 | &__header &__button { 23 | @include tab; 24 | flex: 1; 25 | border: none; 26 | border-bottom: $border-light; 27 | border-width: 2px; 28 | justify-content: space-between; 29 | margin-inline-end: unset; 30 | cursor: pointer; 31 | font-weight: $font-weight-semi-bold; 32 | 33 | &:hover { 34 | color: $dark-gray; 35 | } 36 | 37 | &--expanded { 38 | color: $primary; 39 | border-color: $dark-gray; 40 | 41 | &:hover { 42 | color: $primary; 43 | border-color: $dark-gray; 44 | } 45 | } 46 | } 47 | 48 | &__button &__icon { 49 | display: inline-block; 50 | background: url(./resources/images/chevron-down.svg) center center / cover no-repeat; 51 | margin: 0 $space-s ; 52 | height: 16px; 53 | width: 16px; 54 | } 55 | 56 | &__title { 57 | display: flex; 58 | align-items: center; 59 | } 60 | 61 | .cmp-accordion__button.cmp-accordion__button--expanded &__icon { 62 | transform: rotate(180deg); 63 | -webkit-transform: rotate(180deg); 64 | } 65 | 66 | &__panel { 67 | @include tab-panel; 68 | } 69 | 70 | @include repeatability-buttons 71 | } -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard-scss", 3 | "plugins": [ 4 | "stylelint-use-logical-spec" 5 | ], 6 | "rules": { 7 | "declaration-colon-newline-after": null, 8 | "selector-list-comma-newline-after": null, 9 | "at-rule-empty-line-before": null, 10 | "declaration-colon-space-before": null, 11 | "declaration-empty-line-before": null, 12 | "custom-property-empty-line-before": null, 13 | "comment-empty-line-before": null, 14 | "scss/double-slash-comment-empty-line-before": null, 15 | "scss/dollar-variable-colon-space-after": null, 16 | "custom-property-pattern": null, 17 | "declaration-block-no-duplicate-properties": null, 18 | "declaration-block-no-redundant-longhand-properties": null, 19 | "declaration-block-no-shorthand-property-overrides": null, 20 | "declaration-block-single-line-max-declarations": null, 21 | "font-family-no-duplicate-names": null, 22 | "function-url-quotes": null, 23 | "keyframes-name-pattern": null, 24 | "max-line-length": null, 25 | "no-descending-specificity": null, 26 | "no-duplicate-selectors": null, 27 | "scss/at-extend-no-missing-placeholder": null, 28 | "scss/at-import-partial-extension": null, 29 | "scss/at-mixin-pattern": null, 30 | "scss/comment-no-empty": null, 31 | "scss/dollar-variable-pattern": null, 32 | "scss/double-slash-comment-whitespace-inside": null, 33 | "scss/no-global-function-names": null, 34 | "scss/operator-no-unspaced": null, 35 | "selector-class-pattern": null, 36 | "selector-id-pattern": null, 37 | "liberty/use-logical-spec": ["always", { "except": ["float"] }] 38 | } 39 | } -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | 7 | ## Related Issue 8 | 9 | 10 | 11 | 12 | 13 | 14 | ## Motivation and Context 15 | 16 | 17 | 18 | ## How Has This Been Tested? 19 | 20 | 21 | 22 | 23 | 24 | ## Screenshots (if appropriate): 25 | 26 | ## Types of changes 27 | 28 | 29 | 30 | - [ ] Bug fix (non-breaking change which fixes an issue) 31 | - [ ] New feature (non-breaking change which adds functionality) 32 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 33 | 34 | ## Checklist: 35 | 36 | 37 | 38 | 39 | - [ ] I have signed the [Adobe Open Source CLA](http://opensource.adobe.com/cla.html). 40 | - [ ] My change requires a change to the documentation. 41 | - [ ] I have updated the documentation accordingly. 42 | - [ ] I have read the **CONTRIBUTING** document. 43 | - [ ] I have added tests to cover my changes and the overall coverage did not decrease. 44 | - [ ] All unit tests pass on CircleCi. 45 | - [ ] I ran all tests locally and they pass. -------------------------------------------------------------------------------- /src/site/_fonts.scss: -------------------------------------------------------------------------------- 1 | 2 | //== Font loading 3 | 4 | @mixin fontface($name, $file, $weight: normal, $style: normal) { 5 | @font-face { 6 | font-weight: $weight; 7 | font-family: '#{$name}'; 8 | font-style: $style; 9 | src: url('resources/fonts/#{$file}.ttf') format('truetype'); 10 | } 11 | } 12 | 13 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-Black', bolder); 14 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-BlackItalic', bolder, italic); 15 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-Bold', bolder); 16 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-BoldItalic', bolder, italic); 17 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-ExtraLight', lighter); 18 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-ExtraLightItalic', lighter, italic); 19 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-Italic', normal, italic); 20 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-Light', lighter); 21 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-LightItalic', lighter, italic); 22 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-Regular', normal); 23 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-SemiBold', bold); 24 | @include fontface(defaultFont, 'SourceSansPro/SourceSansPro-SemiBoldItalic', bold, italic); 25 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-Black', bolder); 26 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-BlackItalic', bolder, italic); 27 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-Bold', bolder); 28 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-BoldItalic', bolder, italic); 29 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-ExtraLight', lighter); 30 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-ExtraLightItalic', lighter, italic); 31 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-Italic', normal, italic); 32 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-Light', lighter); 33 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-LightItalic', lighter, italic); 34 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-Regular', normal); 35 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-SemiBold', bold); 36 | @include fontface(titleFont, 'SourceSerifPro/SourceSerifPro-SemiBoldItalic', bold, italic); 37 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish On NPMJS 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - closed 7 | branches: 8 | - main 9 | 10 | jobs: 11 | publish: 12 | if: github.event.pull_request.merged == true 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v2 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Set up Node.js 22 | uses: actions/setup-node@v2 23 | with: 24 | node-version: '20' 25 | registry-url: https://registry.npmjs.org/ 26 | 27 | - name: Set Git Config 28 | run: | 29 | git config --global user.email "ci-build@aemforms" 30 | git config --global user.name "ci-build" 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.ADOBE_GH_TOKEN }} 33 | GH_TOKEN: ${{ secrets.ADOBE_GH_TOKEN }} 34 | 35 | - name: Install dependencies 36 | run: npm install 37 | 38 | - name: Build theme 39 | run: npm run build 40 | 41 | - name: Authenticate with NPM Registry 42 | run: | 43 | echo "registry=https://registry.npmjs.org/" >> .npmrc 44 | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc 45 | npm whoami 46 | env: 47 | NPM_TOKEN: ${{ secrets.NPM_DEPLOY_TOKEN }} 48 | 49 | - name: Discard Uncommitted Changes 50 | run: git reset --hard 51 | 52 | - name: Get current version 53 | id: get_version 54 | run: echo ::set-output name=version::$(node -p "require('./package.json').version") 55 | 56 | - name: Bump version 57 | id: bump_version 58 | run: | 59 | npm version patch -m "Bump version to %s" 60 | 61 | - name: Backup original package.json 62 | run: cp package.json package.json.bak 63 | 64 | - name: Modify package.json for scoped publish 65 | run: | 66 | jq '.name = "@aemforms/af-easel-theme"' package.json > package.json.tmp && mv package.json.tmp package.json 67 | 68 | - name: Publish to npm 69 | run: | 70 | npm publish --access public 71 | env: 72 | NODE_AUTH_TOKEN: ${{ secrets.NPM_DEPLOY_TOKEN }} 73 | NPM_TOKEN: ${{ secrets.NPM_DEPLOY_TOKEN }} 74 | 75 | - name: Restore original package.json 76 | run: mv package.json.bak package.json 77 | 78 | - name: Push changes to remote repository 79 | run: git push origin HEAD:main 80 | env: 81 | GITHUB_TOKEN: ${{ secrets.ADOBE_GH_TOKEN }} 82 | GH_TOKEN: ${{ secrets.ADOBE_GH_TOKEN }} 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # dont include parcel cache into the final theme.zip file 3 | .parcel-cache 4 | .DS_Store 5 | 6 | # make sure no .env file is present in the theme.zip file - AEM adds this file when downloading the theme 7 | .env 8 | 9 | ### IntelliJ ### 10 | .idea/ 11 | *.iml 12 | 13 | # Logs 14 | logs 15 | *.log 16 | npm-debug.log* 17 | yarn-debug.log* 18 | yarn-error.log* 19 | lerna-debug.log* 20 | 21 | # Diagnostic reports (https://nodejs.org/api/report.html) 22 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 23 | 24 | # Runtime data 25 | pids 26 | *.pid 27 | *.seed 28 | *.pid.lock 29 | 30 | # Directory for instrumented libs generated by jscoverage/JSCover 31 | lib-cov 32 | 33 | # Coverage directory used by tools like istanbul 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | .nyc_output 39 | 40 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 41 | .grunt 42 | 43 | # Bower dependency directory (https://bower.io/) 44 | bower_components 45 | 46 | # node-waf configuration 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | build/Release 51 | 52 | # Dependency directories 53 | node_modules/ 54 | jspm_packages/ 55 | 56 | # TypeScript v1 declaration files 57 | typings/ 58 | 59 | # TypeScript cache 60 | *.tsbuildinfo 61 | 62 | # Optional npm cache directory 63 | .npm 64 | 65 | # Optional eslint cache 66 | .eslintcache 67 | 68 | # Microbundle cache 69 | .rpt2_cache/ 70 | .rts2_cache_cjs/ 71 | .rts2_cache_es/ 72 | .rts2_cache_umd/ 73 | 74 | # Optional REPL history 75 | .node_repl_history 76 | 77 | # Output of 'npm pack' 78 | *.tgz 79 | 80 | # Yarn Integrity file 81 | .yarn-integrity 82 | 83 | # dotenv environment variables file 84 | .env 85 | .env.test 86 | 87 | # parcel-bundler cache (https://parceljs.org/) 88 | .cache 89 | 90 | # Next.js build output 91 | .next 92 | 93 | # Nuxt.js build / generate output 94 | .nuxt 95 | dist 96 | 97 | # Gatsby files 98 | .cache/ 99 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 100 | # https://nextjs.org/blog/next-9-1#public-directory-support 101 | # public 102 | 103 | # vuepress build output 104 | .vuepress/dist 105 | 106 | # Serverless directories 107 | .serverless/ 108 | 109 | # FuseBox cache 110 | .fusebox/ 111 | 112 | # DynamoDB Local files 113 | .dynamodb/ 114 | 115 | # TernJS port file 116 | .tern-port 117 | 118 | # Theme client libs generated output 119 | theme-clientlibs -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | 2 | # dont include parcel cache into the final theme.zip file 3 | .parcel-cache 4 | .DS_Store 5 | .parcelrc 6 | 7 | # dont include github workflows 8 | .github 9 | 10 | # make sure no .env file is present in the theme.zip file - AEM adds this file when downloading the theme 11 | .env 12 | env_template 13 | 14 | 15 | ### IntelliJ ### 16 | .idea/ 17 | *.iml 18 | 19 | # Logs 20 | logs 21 | *.log 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | lerna-debug.log* 26 | 27 | # Diagnostic reports (https://nodejs.org/api/report.html) 28 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 29 | 30 | # Runtime data 31 | pids 32 | *.pid 33 | *.seed 34 | *.pid.lock 35 | 36 | # Directory for instrumented libs generated by jscoverage/JSCover 37 | lib-cov 38 | 39 | # Coverage directory used by tools like istanbul 40 | coverage 41 | *.lcov 42 | 43 | # nyc test coverage 44 | .nyc_output 45 | 46 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 47 | .grunt 48 | 49 | # Bower dependency directory (https://bower.io/) 50 | bower_components 51 | 52 | # node-waf configuration 53 | .lock-wscript 54 | 55 | # Compiled binary addons (https://nodejs.org/api/addons.html) 56 | build/Release 57 | 58 | # source files 59 | src/ 60 | 61 | # Dependency directories 62 | node_modules/ 63 | jspm_packages/ 64 | 65 | # TypeScript v1 declaration files 66 | typings/ 67 | 68 | # TypeScript cache 69 | *.tsbuildinfo 70 | 71 | # Optional npm cache directory 72 | .npm 73 | 74 | # Optional eslint cache 75 | .eslintcache 76 | 77 | # Microbundle cache 78 | .rpt2_cache/ 79 | .rts2_cache_cjs/ 80 | .rts2_cache_es/ 81 | .rts2_cache_umd/ 82 | 83 | # Optional REPL history 84 | .node_repl_history 85 | 86 | # Output of 'npm pack' 87 | *.tgz 88 | 89 | # Yarn Integrity file 90 | .yarn-integrity 91 | 92 | # dotenv environment variables file 93 | .env 94 | .env.test 95 | 96 | # parcel-bundler cache (https://parceljs.org/) 97 | .cache 98 | 99 | # Next.js build output 100 | .next 101 | 102 | # Nuxt.js build / generate output 103 | .nuxt 104 | 105 | # Gatsby files 106 | .cache/ 107 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 108 | # https://nextjs.org/blog/next-9-1#public-directory-support 109 | # public 110 | 111 | # vuepress build output 112 | .vuepress/dist 113 | 114 | # Serverless directories 115 | .serverless/ 116 | 117 | # FuseBox cache 118 | .fusebox/ 119 | 120 | # DynamoDB Local files 121 | .dynamodb/ 122 | 123 | # TernJS port file 124 | .tern-port 125 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "af-easel-theme", 3 | "version": "1.0.11", 4 | "description": "Standard AEM Forms Easel theme", 5 | "license": "MIT License, Copyright 2022 Adobe Systems Incorporated", 6 | "scripts": { 7 | "build": "rimraf dist && mkdir dist && parcel build src/theme.ts --no-cache --dist-dir dist && npm run postcss", 8 | "postcss": "node post-css.js", 9 | "watch": "parcel watch src/theme.ts", 10 | "proxy": "aem-site-theme-builder live", 11 | "live": "npm-run-all -p watch proxy", 12 | "create-zip": "cd dist/ && zip ./theme.zip ./* -r", 13 | "deploy-zip": "node scripts/deploy-zip.mjs", 14 | "clientlib-generator": "node clientlib-generator.js", 15 | "create-clientlib": "npm run build && npm run clientlib-generator", 16 | "stylelint": "stylelint src/*/*{.css,scss}", 17 | "stylelint:fix": "stylelint --fix src/*/*{.css,scss}" 18 | }, 19 | "devDependencies": { 20 | "@adobe/aem-site-theme-builder": "6.0.0", 21 | "@parcel/transformer-sass": "^2.0.1", 22 | "aem-clientlib-generator": "^1.8.0", 23 | "autoprefixer": "^10.3.7", 24 | "browser-sync": "^3.0.4", 25 | "install": "^0.13.0", 26 | "normalize.css": "^8.0.1", 27 | "npm": "^11.4.2", 28 | "npm-run-all": "^4.1.5", 29 | "parcel": "^2.0.1", 30 | "parcel-namer-rewrite": "^2.0.0-rc.1", 31 | "path": "^0.12.7", 32 | "postcss-media-minmax": "^5.0.0", 33 | "process": "^0.11.10", 34 | "rimraf": "^3.0.2", 35 | "stylelint": "^14.16.1", 36 | "stylelint-config-standard": "^25.0.0", 37 | "stylelint-config-standard-scss": "^4.0.0", 38 | "stylelint-csstree-validator": "3.0.0", 39 | "stylelint-formatter-pretty": "^3.1.1", 40 | "stylelint-scss": "5.2.1", 41 | "stylelint-use-logical-spec": "^5.0.0", 42 | "typescript": "^4.5.2" 43 | }, 44 | "dependencies": { 45 | "jszip": "^3.10.1" 46 | }, 47 | "publishConfig": { 48 | "access": "public" 49 | }, 50 | "parcel-namer-rewrite": { 51 | "chain": "@parcel/namer-default", 52 | "rules": { 53 | "(.*?)(\\.[a-f0-9]{8})?\\.(ttf|woff2?)": "resources/fonts/$1.$3", 54 | "(.*?)(\\.[a-f0-9]{8})?\\.(svg|png|gif|jpg|jpeg|webp)": "resources/images/$1.$3" 55 | } 56 | }, 57 | "postcss": { 58 | "plugins": { 59 | "autoprefixer": { 60 | "overrideBrowserslist": [ 61 | "> 1%", 62 | "last 2 versions" 63 | ] 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AEM Forms Easel Theme 2 | 3 | This is the standard Easel theme for Adobe Experience Manager (AEM) Forms. 4 | 5 | This theme can be modified to customize the visual appearance of Adaptive Form. 6 | 7 | ## Usage 8 | 9 | If you're using CSS modules in JavaScript, you can install the NPM module: 10 | 11 | ``` 12 | npm install --save @aemforms/af-easel-theme 13 | ``` 14 | 15 | Then just import the files as you would other CSS. 16 | 17 | ``` 18 | import '@aemforms/af-easel-theme/dist/theme.css'; 19 | ``` 20 | 21 | ## Structure 22 | 23 | * `src/theme.ts`: This is the main entry point of your JS & CSS theme. 24 | * `src/site`: Files that are generic to the entire site. 25 | * `src/components`: Files that are specific to components. 26 | * `src/resources`: Associated files, like icons, logos, fonts. 27 | 28 | 29 | ## Complete development workflow 30 | 31 | In order to make best use of theme-builder you have to run the live preview which provides proxy and browser sync functionalities. On top of that you need to make sure that you have additional watcher for your source files that triggers your theme build process which produces changes in the `dist` folder of your theme. This way after making change in your source file you will get your proxy page refreshed via browser sync. 32 | 33 | ### NodeJS Version 34 | This theme has been developed and tested with node version 20.13.1. 35 | 36 | ### Build 37 | 38 | Initialize the project with following command executed at the theme root: 39 | 40 | ``` 41 | npm install 42 | npm run build 43 | ``` 44 | 45 | ### Creating Clientlib for AEM 65 46 | In AEM 65, core-component themes are deployed as clientlibs. To create clientlib from theme: 47 | ``` 48 | npm run create-clientlib --category="adaptiveform.theme.yourtheme" 49 | ``` 50 | This takes to args 51 | 1. category [Required] : Clientlib category 52 | 2. directory : Where should the clientlib be created 53 | 54 | ### Environment Variables 55 | 56 | Theme Builder scripts are based on the environment variables you provide. These variables are used to properly provide live preview and deploy functionality of the AEM Site Theme Builder. 57 | 58 | Here is the list of required variables: 59 | 60 | ``` 61 | AEM_URL= 62 | AEM_SITE= 63 | AEM_PROXY_PORT= 64 | ``` 65 | Here is the list of optional variables: 66 | 67 | ``` 68 | AEM_ADAPTIVE_FORM= 69 | ``` 70 | Recommended way to define site variables is to use / create `.env` file within your theme project repository. 71 | 72 | ### Launch 73 | 74 | Run the local proxy server while working to preview your changes with the content from the production environment. 75 | 76 | ``` 77 | npm run live 78 | ``` 79 | 80 | Once your work completed, check your changes into GitHub, and execute the deployment pipeline in Cloud Manager. 81 | 82 | ## Contributing 83 | 84 | Contributions are welcomed! Read the [Contributing Guide](.github/CONTRIBUTING.md) for more information. 85 | 86 | ## Licensing 87 | 88 | This project is licensed under the MIT License. See [LICENSE](LICENSE) for more information. 89 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Adobe Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language. 18 | * Being respectful of differing viewpoints and experiences. 19 | * Gracefully accepting constructive criticism. 20 | * Focusing on what is best for the community. 21 | * Showing empathy towards other community members. 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances. 27 | * Trolling, insulting/derogatory comments, and personal or political attacks. 28 | * Public or private harassment. 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission. 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting. 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at Grp-opensourceoffice@adobe.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [https://contributor-covenant.org/version/1/4][version]. 72 | 73 | [homepage]: https://contributor-covenant.org 74 | [version]: https://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /src/site/_grid.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * ADOBE CONFIDENTIAL 3 | * 4 | * Copyright 2020 Adobe Systems Incorporated 5 | * All Rights Reserved. 6 | * 7 | * NOTICE: All information contained herein is, and remains 8 | * the property of Adobe Systems Incorporated and its suppliers, 9 | * if any. The intellectual and technical concepts contained 10 | * herein are proprietary to Adobe Systems Incorporated and its 11 | * suppliers and may be covered by U.S. and Foreign Patents, 12 | * patents in process, and are protected by trade secret or copyright law. 13 | * Dissemination of this information or reproduction of this material 14 | * is strictly forbidden unless prior written permission is obtained 15 | * from Adobe Systems Incorporated. 16 | */ 17 | 18 | /* grid component */ 19 | .aem-Grid { 20 | display: block; 21 | width: 100%; 22 | } 23 | 24 | .aem-Grid::before, 25 | .aem-Grid::after { 26 | display: table; 27 | content: ' '; 28 | } 29 | 30 | .aem-Grid::after { 31 | clear: both; 32 | } 33 | 34 | /* placeholder for new components */ 35 | .aem-Grid-newComponent { 36 | clear: both; 37 | margin: 0; 38 | } 39 | 40 | /* column of a grid */ 41 | .aem-GridColumn { 42 | clear: both; 43 | box-sizing: border-box; 44 | } 45 | 46 | /* force showing hidden */ 47 | .aem-GridShowHidden > .aem-Grid > .aem-GridColumn { 48 | display: block !important; 49 | } 50 | 51 | /* force showing hidden components in unhide mode */ 52 | .aem-GridShowHidden > .cmp-container > .aem-Grid > .aem-GridColumn { 53 | display: block !important; 54 | } 55 | 56 | /* Generates all the rules for the grid columns up to the given amount of column */ 57 | @mixin generate-columns($breakPoint, $columnTotal, $column: 1) { 58 | @if ($column <= $columnTotal) { 59 | & > .aem-GridColumn.aem-GridColumn--#{$breakPoint}--#{$column} { 60 | float: left; 61 | clear: none; 62 | width: ($column * 100% / $columnTotal); 63 | } 64 | 65 | @include generate-columns($breakPoint, $columnTotal, ($column + 1)); 66 | } 67 | } 68 | 69 | /* Generates all the rules for the grid column offset up to the given amount of column */ 70 | @mixin generate-offsets($breakPoint, $columnTotal, $column: 0) { 71 | @if ($column <= $columnTotal) { 72 | & > .aem-GridColumn.aem-GridColumn--offset--#{$breakPoint}--#{$column} { 73 | margin-left: ($column * 100% / $columnTotal); 74 | } 75 | 76 | @include generate-offsets($breakPoint, $columnTotal, ($column + 1)); 77 | } 78 | } 79 | 80 | /* Generates all the rules for the grid and columns for the given break point and total of columns */ 81 | @mixin generate-grid-columns($breakPoint, $columnTotal) { 82 | @if ($columnTotal > 0) { 83 | &.aem-Grid--#{$columnTotal} { 84 | @include generate-columns($breakPoint, $columnTotal); 85 | @include generate-offsets($breakPoint, $columnTotal); 86 | } 87 | 88 | &.aem-Grid--#{$breakPoint}--#{$columnTotal} { 89 | @include generate-columns($breakPoint, $columnTotal); 90 | @include generate-offsets($breakPoint, $columnTotal); 91 | } 92 | } 93 | } 94 | 95 | /* Generates all the rules for the grids and columns */ 96 | @mixin grid-loop($breakPoint, $columnTotal, $column: 1) { 97 | @if ($column <= $columnTotal) { 98 | @include generate-grid-columns($breakPoint, $column); 99 | @include grid-loop($breakPoint, $columnTotal, ($column + 1)); 100 | } 101 | } 102 | 103 | /* API function to be called to generate a grid config */ 104 | @mixin generate-grid($breakPoint, $columnTotal) { 105 | @include grid-loop($breakPoint, $columnTotal); 106 | 107 | & > .aem-GridColumn.aem-GridColumn--#{$breakPoint}--newline { 108 | /* newline behavior */ 109 | display: block; 110 | clear: both !important; 111 | } 112 | 113 | & > .aem-GridColumn.aem-GridColumn--#{$breakPoint}--none { 114 | /* none behavior */ 115 | display: block; 116 | float: left; // Enforce the float positioning to maintain the column height and position relative to previous columns 117 | clear: none !important; // Prevent the clear:both effect of another breakpoint new line 118 | } 119 | 120 | & > .aem-GridColumn.aem-GridColumn--#{$breakPoint}--hide { 121 | /* hide behavior */ 122 | display: none; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for choosing to contribute! 4 | 5 | The following are a set of guidelines to follow when contributing to this project. 6 | 7 | ## Code Of Conduct 8 | 9 | This project adheres to the Adobe [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to the team. 10 | 11 | ## Contributor License Agreement 12 | 13 | All third-party contributions to this project must be accompanied by a signed contributor license agreement. This gives Adobe permission to redistribute your contributions as part of the project. [Sign our CLA](http://opensource.adobe.com/cla.html). You only need to submit an Adobe CLA one time, so if you have submitted one previously, you are good to go! 14 | 15 | ## How to contribute 16 | 17 | New code contributions should be made primarily using GitHub pull requests. This involves creating a fork of the project in your personal space, adding your new code in a branch and triggering a pull request. 18 | 19 | See how to perform pull requests at https://help.github.com/articles/using-pull-requests. 20 | 21 | Please follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when submitting a pull request! 22 | 23 | To ease the review process of pull requests, we ask you to please follow a number of guidelines and recommendations. This will speed up the review process and ensure that a pull request does not break any existing functionality. 24 | * **Keep it small!** Reviewing a large pull request is very difficult and time consuming. Try to keep your contribution small, maybe to a maximum of a dozen files with maximum a few hundred lines of code in total. Do not combine multiple new features or bug fixes into one single pull request: if one PR needs another one, simply create multiple PRs, and open "nested PRs" that depend on each other. 25 | * **Do not remove tests!** If your feature breaks a test, do NOT remove that test, unless there is a very good reason that the test is no longer needed. If there is a test for something, there is usually a good reason for that. If you break a test, make sure that you fix the test, but make sure that the original feature still does what it is expected to do! 26 | * **Add your own tests!**: We will not consider pull requests that do not include a minimum of 80% test coverage. Make sure that your tests follow the same design and format than similar tests, and be consistent with our existing tests. 27 | * **Do not "pollute" your pull request!**: Avoid unneeded changes in your pull request, for example, code formatting changes or changes not related to your feature or bug fix. Make sure that your IDE is configured to **not** reformat the entire files you are editing, but only the lines you change. This will ensure that different formatting rules will not affect code that you do not change! 28 | * **Follow master!**: Make sure that your pull request is up-to-date with respect to our `master` branch. It is your responsibility to ensure that the latest commits in our `master` branch are always merged into your code, and that merge conflicts are resolved. Please make sure that your pull request follows our recommendations, in order to speed up the review process and hopefully reduce the number of times you will have to merge our latest changes into your branch. 29 | * **Format your code!**: Our maven build can automatically format java files, make sure you do that. For other file formats like `.js`, `.xml` and `.html`, make sure that you use a 4-space indentation, do not use tabs. For `.json` files, we use a 2-space indentation. 30 | * **Use common sense!**: Use common sense to increase the quality of your contribution. Do not duplicate code, use constants instead of hard-coded strings where appropriate, add javadoc documentation, use comments (sparingly!) where the code could be difficult to understand, and keep in mind that the Forms components can be reused and extended by others so make sure the code is readable and follows the latest AEM development guidelines. 31 | 32 | ## New Feature request 33 | Please follow the [feature template](ISSUE_TEMPLATE/FEATURE_REQUEST.md) to open new feature requests. 34 | 35 | 36 | ## Issues 37 | 38 | Please follow the [issue template](ISSUE_TEMPLATE/BUG_REPORT.md) to open new [issues](https://github.com/adobe/aem-core-forms-components/issues) and join the conversations to provide feedback. -------------------------------------------------------------------------------- /src/site/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin container { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | 6 | &[data-cmp-valid=false] input, 7 | &[data-cmp-valid=false] textarea, 8 | &[data-cmp-valid=false] select { 9 | background: $light-error ; 10 | border: $border-error ; 11 | outline-color: $error; 12 | } 13 | 14 | &[data-cmp-valid=false]>&__shortdescription { 15 | display: none; 16 | } 17 | 18 | &[data-cmp-valid=false]>&__errormessage { 19 | display: flex; 20 | align-items: center; 21 | } 22 | 23 | @include required-field-style; 24 | 25 | // remove this code 26 | &.cmp-tabs, 27 | &.cmp-adaptiveform-wizard, 28 | &.cmp-accordion { 29 | margin: $space-l 0; 30 | } 31 | 32 | } 33 | 34 | @mixin required-field-style { 35 | &[data-cmp-required=true] &__label { 36 | display: flex; 37 | justify-content: flex-start; 38 | column-gap: $space-xs; 39 | &::after { 40 | content: '*'; 41 | font-weight: bold; 42 | color: $error; 43 | } 44 | } 45 | } 46 | 47 | @mixin label { 48 | padding-inline-end: $space-m; 49 | box-sizing: border-box; 50 | opacity: 1; 51 | color: $dark-gray; 52 | padding: 0; 53 | font-size: $font-m; 54 | pointer-events: none; 55 | z-index: 11; 56 | } 57 | 58 | @mixin checkbox-label { 59 | pointer-events: all; 60 | display: flex; 61 | align-items: center; 62 | gap: $space-s; 63 | width: 100%; 64 | } 65 | 66 | @mixin panel-label { 67 | font-size: $font-l; 68 | font-weight: $font-weight-semi-bold; 69 | color: $dark-gray; 70 | opacity: 1; 71 | margin-top: 0; 72 | margin-bottom: $space-s; 73 | position: static; 74 | } 75 | 76 | @mixin widget { 77 | border-radius: 0; 78 | font-size: $font-m; 79 | height: $field-height; 80 | background-color: transparent; 81 | border: $border-dark; 82 | border-radius: $field-radius; 83 | padding: 0 $space-s; 84 | margin: $space-xs 0; 85 | outline: $focus-outline; 86 | outline-width: 0px; 87 | box-sizing: border-box; 88 | 89 | &:hover:not([disabled]) { 90 | border: $border-darker; 91 | transition: border 0.3s ease-out; 92 | } 93 | 94 | &:focus:not([disabled]) { 95 | background-color: white; 96 | border-color: transparent; 97 | outline-offset: 0; 98 | outline: $focus-outline; 99 | transition: outline 0.1s ease-out, border 0.1s ease-out; 100 | } 101 | 102 | &:disabled { 103 | background-color: $disabled-color; 104 | } 105 | 106 | &[readonly] { 107 | border: none; 108 | border-bottom: $border-light; 109 | border-radius: 0; 110 | } 111 | } 112 | 113 | @mixin long-description { 114 | display: flex; 115 | align-items: flex-start; 116 | background-color: $background-color; 117 | border-radius: $field-radius; 118 | opacity: 1; 119 | color: $dark-gray; 120 | padding: $space-s; 121 | font-size: $font-s; 122 | font-weight: 500; 123 | pointer-events: none; 124 | margin: $space-xs 0; 125 | column-gap: $space-s; 126 | 127 | &::before { 128 | content: ''; 129 | background: url(./resources/images/long-description.svg) center center / cover no-repeat; 130 | height: 16px; 131 | min-width: 16px; 132 | } 133 | 134 | p { 135 | margin: 0; 136 | } 137 | } 138 | 139 | @mixin short-description { 140 | display: flex; 141 | position: static; 142 | font-size: $font-s; 143 | font-weight: 500; 144 | color: $gray; 145 | margin: 0 0 $space-s 0; 146 | } 147 | 148 | @mixin question-mark { 149 | position: absolute; 150 | display: flex; 151 | top: 0; 152 | inset-inline-end: 0; 153 | padding: 0; 154 | width: $font-m; 155 | height: $font-m; 156 | border-radius: 9px; 157 | background: url(./resources/images/question.svg) center center / cover no-repeat; 158 | cursor: pointer; 159 | border: none; 160 | } 161 | 162 | @mixin error-message { 163 | display: none; 164 | color: $error; 165 | font-size: $font-s; 166 | font-weight: 500; 167 | margin: 0; 168 | 169 | &::before { 170 | content: ''; 171 | background: url(./resources/images/error.svg) center center / cover no-repeat; 172 | margin-inline-end: $space-xs; 173 | height: 16px; 174 | min-width: 16px; 175 | } 176 | } 177 | 178 | // description contains the long-description, short-description, question-mark 179 | @mixin description { 180 | &__longdescription { 181 | @include long-description; 182 | } 183 | 184 | &__shortdescription { 185 | @include short-description; 186 | } 187 | 188 | &__questionmark { 189 | @include question-mark; 190 | } 191 | 192 | &__label-container { 193 | display: flex; 194 | justify-content: space-between; 195 | &>button[class*=__questionmark] { 196 | position: unset; 197 | inset-inline-end: unset; 198 | } 199 | } 200 | } 201 | 202 | // input contains the container, label, widget, description, error 203 | @mixin input { 204 | @include container; 205 | 206 | &__label { 207 | @include label; 208 | } 209 | 210 | &__widget { 211 | @include widget; 212 | } 213 | 214 | @include description; 215 | 216 | &__errormessage { 217 | @include error-message 218 | } 219 | } 220 | 221 | @mixin focused-button { 222 | position: relative; 223 | box-shadow: 0 6px 12px 1px rgba($color: #000000, $alpha: .25); 224 | transform: translateY(-5%); 225 | scale: 102%; 226 | transition: box-shadow 0.1s ease-out, transform 0.1s ease-out; 227 | } 228 | 229 | @mixin primary-button { 230 | width: 100%; 231 | display: block; 232 | background: $primary; 233 | border: none; 234 | border-radius: 500px; 235 | height: $tap-height; 236 | padding: 0 $space-m; 237 | cursor: pointer; 238 | color: white; 239 | font-size: $font-m; 240 | font-weight: $font-weight-semi-bold; 241 | font-family: defaultFont, "Helvetica Neue", Helvetica, Arial, sans-serif; 242 | 243 | &:hover:not([disabled]) { 244 | @include focused-button; 245 | } 246 | 247 | &:focus-visible:not([disabled]) { 248 | @include focused-button; 249 | } 250 | 251 | &:disabled { 252 | background-color: $disabled-color; 253 | cursor: default; 254 | } 255 | 256 | &[data-cmp-enabled]:not([data-cmp-enabled=true]) { 257 | background: $gray; 258 | color: $very-light-gray; 259 | } 260 | 261 | @media (min-width: 640px) { 262 | width: fit-content; 263 | } 264 | } 265 | 266 | @mixin secondary-base-button { 267 | width: 100%; 268 | display: flex; 269 | justify-content: center; 270 | position: static; 271 | align-self: flex-start; 272 | background: $background-color; 273 | border-radius: 500px; 274 | box-shadow: 0 6px 12px 1px rgba($color: #000000, $alpha: 0); 275 | vertical-align: text-bottom; 276 | cursor: pointer; 277 | color: $primary; 278 | font-size: $font-m; 279 | padding: $space-s $space-m; 280 | font-weight: $font-weight-semi-bold; 281 | margin: $space-s 0; 282 | opacity: 1; 283 | 284 | @media (min-width: 640px) { 285 | width: fit-content; 286 | } 287 | } 288 | 289 | @mixin secondary-button { 290 | @include secondary-base-button; 291 | 292 | &:hover { 293 | position: relative; 294 | background-color: $very-light-gray; 295 | box-shadow: 0 6px 12px 1px rgba($color: #000000, $alpha: .075); 296 | transform: translateY(-5%); 297 | scale: 102%; 298 | transition: box-shadow 0.1s ease-out, transform 0.1s ease-out, background-color 0.1s ease-out; 299 | } 300 | 301 | &:disabled { 302 | background-color: $disabled-color; 303 | cursor: default; 304 | } 305 | 306 | } 307 | 308 | // for tabs on top & wizard 309 | @mixin tab-list { 310 | padding: 0 $space-s; 311 | counter-reset: section; 312 | display: flex; 313 | flex-wrap: nowrap; 314 | list-style: none; 315 | margin: 0; 316 | margin-bottom: 0; 317 | overflow: auto; 318 | } 319 | 320 | @mixin tab { 321 | padding: 0; 322 | background-color: transparent; 323 | min-height: $tap-height; 324 | line-height: 1.2; 325 | color: $gray; 326 | margin-inline-end: $space-m; 327 | font-size: $font-m; 328 | display: flex; 329 | align-items: center; 330 | border-radius: 0; 331 | border-width: 2px; 332 | white-space: nowrap; 333 | font-weight: $font-weight-semi-bold; 334 | 335 | &:hover { 336 | color: $dark-gray; 337 | border-bottom-color: $very-light-gray; 338 | border-bottom-style: solid; 339 | } 340 | 341 | &--active { 342 | color: $primary; 343 | border-color: $dark-primary; 344 | border-bottom-style: solid; 345 | display: flex; 346 | align-items: center; 347 | } 348 | 349 | &--active::after { 350 | content: '—'; 351 | display: none; 352 | color: $primary; 353 | } 354 | 355 | &--active:hover { 356 | border-bottom-color: $primary; 357 | border-bottom-style: solid; 358 | } 359 | 360 | } 361 | 362 | @mixin tab-panel { 363 | padding: $space-l; 364 | border: $border-light; 365 | border-width: 1px; 366 | border-radius: $button-radius; 367 | background-color: white; 368 | box-shadow: 0 6px 12px 1px rgba($color: #000000, $alpha: .03); 369 | 370 | @media (max-width: 480px) { 371 | padding-block: $space-m; 372 | padding-inline: $space-s; 373 | width: 100%; 374 | } 375 | &--hidden { 376 | display: none; 377 | } 378 | } 379 | 380 | // wizard tab 381 | @mixin wizard-tab { 382 | @include tab; 383 | column-gap: $space-s; 384 | padding: 0; 385 | border-bottom-width: 2px; 386 | box-sizing: border-box; 387 | display: flex; 388 | align-items: center; 389 | font-size: $font-m; 390 | transition: flex-grow ease .3s; 391 | border-radius: 0; 392 | border-bottom-width: 2px; 393 | border-bottom: $border-light; 394 | border-color: transparent; 395 | 396 | &::before { 397 | counter-increment: section; 398 | content: counter(section); 399 | margin-inline-end: 0; 400 | background-color: $very-light-gray; 401 | padding: 6px; 402 | line-height: .56; 403 | border-radius: $button-radius; 404 | color: $dark-gray; 405 | text-align: center; 406 | font-size: $font-s; 407 | font-weight: bold; 408 | } 409 | 410 | &:last-child { 411 | margin: 0; 412 | } 413 | 414 | &--active { 415 | flex-grow: 1; 416 | transition: flex-grow ease .3s; 417 | color: $primary; 418 | border-bottom: $focus-outline; 419 | background-color: transparent; 420 | } 421 | 422 | &--active::before { 423 | counter-increment: section; 424 | content: counter(section); 425 | margin-inline-end: $space-s; 426 | background-color: $primary; 427 | padding: 6px; 428 | line-height: .56; 429 | border-radius: $button-radius; 430 | color: white; 431 | text-align: center; 432 | font-size: $font-s; 433 | font-weight: bold; 434 | } 435 | } 436 | 437 | @mixin wizard-next-button { 438 | display: flex; 439 | justify-content: center; 440 | align-items: center; 441 | height: $tap-height; 442 | position: static; 443 | cursor: pointer; 444 | @include secondary-button; 445 | 446 | &::before { 447 | content: 'Next'; 448 | position: static; 449 | } 450 | } 451 | 452 | @mixin wizard-previous-button { 453 | display: flex; 454 | justify-content: center; 455 | align-items: center; 456 | height: $tap-height; 457 | position: static; 458 | cursor: pointer; 459 | @include secondary-button; 460 | 461 | &::before { 462 | content: 'Previous'; 463 | position: static; 464 | } 465 | } 466 | 467 | @mixin list-container { 468 | pointer-events: all; 469 | margin: 0; 470 | display: flex; 471 | margin: $space-xs 0; 472 | 473 | &.VERTICAL { 474 | flex-direction: column; 475 | row-gap: 0; 476 | } 477 | 478 | &.HORIZONTAL { 479 | flex-direction: row; 480 | column-gap: 0; 481 | flex-wrap: wrap; 482 | } 483 | } 484 | 485 | @mixin list-item { 486 | pointer-events: all; 487 | display: flex; 488 | align-items: center; 489 | color: $dark-gray; 490 | column-gap: $space-s; 491 | position: static; 492 | opacity: 1; 493 | border-radius: $button-radius; 494 | border: none; 495 | cursor: pointer; 496 | margin: 0; 497 | padding: $space-s; 498 | font-size: $font-m; 499 | 500 | &:hover { 501 | background-color: $background-color; 502 | transition: background-color 0.3s ease-out, color 0.3s ease-out; 503 | color: $dark-gray; 504 | } 505 | 506 | &:focus-within { 507 | outline: $focus-outline; 508 | } 509 | } 510 | 511 | @mixin repeatability-icon-default { 512 | background-color: $very-light-gray; 513 | width: 1.75rem; 514 | border: 0; 515 | height: 1.75rem; 516 | border-radius: 50%; 517 | padding: 5px 5px; 518 | cursor: pointer; 519 | } 520 | 521 | @mixin repeatability-buttons { 522 | &__repeatable-buttons { 523 | display: flex; 524 | align-items: center; 525 | background: transparent; 526 | gap: 5px; 527 | 528 | .cmp-accordion__add-button { 529 | background: url('./resources/images/add-button.svg') 50% 50% no-repeat; 530 | @include repeatability-icon-default; 531 | 532 | &:hover { 533 | background: url('./resources/images/add-button-white.svg') 50% 50% no-repeat; 534 | background-color: $primary; 535 | box-shadow: 0px 3px 12px #00000033; 536 | } 537 | } 538 | 539 | .cmp-accordion__remove-button { 540 | background: url('./resources/images/remove-button.svg') 50% 50% no-repeat; 541 | @include repeatability-icon-default; 542 | 543 | &:hover { 544 | background-color: $error; 545 | box-shadow: 0px 3px 12px #00000033; 546 | } 547 | } 548 | } 549 | } 550 | 551 | div[data-cmp-is="adaptiveFormDropDown"], 552 | div[data-cmp-is="adaptiveFormDatePicker"], 553 | div[data-cmp-is="adaptiveFormNumberInput"], 554 | div[data-cmp-is="adaptiveFormTextInput"], 555 | div[data-cmp-is="adaptiveFormCheckBoxGroup"], 556 | div[data-cmp-is="adaptiveFormFileInput"], 557 | div[data-cmp-is="adaptiveFormRadioButton"], 558 | div[data-cmp-is="adaptiveFormEmailInput"], 559 | div[data-cmp-is="adaptiveFormTelephoneInput"] { 560 | border: none; 561 | margin: $space-s 0; 562 | } --------------------------------------------------------------------------------