payload 0.20.10-beta.0 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +592 -853
  2. package/components/styles.css +1 -1
  3. package/dist/admin/components/elements/Banner/index.scss +1 -0
  4. package/dist/admin/components/elements/Nav/index.js +2 -2
  5. package/dist/admin/components/forms/field-types/Array/Array.js +1 -1
  6. package/dist/admin/components/forms/field-types/Blocks/Blocks.js +1 -1
  7. package/dist/admin/components/forms/field-types/Checkbox/index.js +1 -1
  8. package/dist/admin/components/forms/field-types/Code/Code.js +1 -1
  9. package/dist/admin/components/forms/field-types/DateTime/index.js +1 -1
  10. package/dist/admin/components/forms/field-types/Email/index.js +2 -2
  11. package/dist/admin/components/forms/field-types/Group/index.js +1 -1
  12. package/dist/admin/components/forms/field-types/HiddenInput/index.js +1 -1
  13. package/dist/admin/components/forms/field-types/Number/index.js +2 -2
  14. package/dist/admin/components/forms/field-types/Password/index.js +2 -2
  15. package/dist/admin/components/forms/field-types/Point/index.js +4 -4
  16. package/dist/admin/components/forms/field-types/RadioGroup/Input.js +1 -1
  17. package/dist/admin/components/forms/field-types/Relationship/index.js +1 -1
  18. package/dist/admin/components/forms/field-types/RichText/RichText.js +2 -2
  19. package/dist/admin/components/forms/field-types/RichText/elements/upload/Element/index.scss +12 -1
  20. package/dist/admin/components/forms/field-types/RichText/index.scss +7 -0
  21. package/dist/admin/components/forms/field-types/Select/Input.js +2 -2
  22. package/dist/admin/components/forms/field-types/Text/Input.js +2 -2
  23. package/dist/admin/components/forms/field-types/Textarea/Input.js +2 -2
  24. package/dist/admin/components/forms/field-types/Upload/Input.js +1 -1
  25. package/dist/admin/components/views/Global/Default.js +1 -1
  26. package/dist/admin/scss/type.scss +1 -1
  27. package/docs/admin/overview.mdx +4 -0
  28. package/docs/authentication/config.mdx +49 -18
  29. package/package.json +7 -12
  30. package/dist/collections/graphql/resolvers/resolvers.spec.d.ts +0 -1
  31. package/dist/collections/graphql/resolvers/resolvers.spec.js +0 -360
  32. package/dist/collections/operations/local/local.spec.d.ts +0 -1
  33. package/dist/collections/operations/local/local.spec.js +0 -196
  34. package/dist/collections/tests/collections.spec.d.ts +0 -1
  35. package/dist/collections/tests/collections.spec.js +0 -736
  36. package/dist/collections/tests/defaultValue.spec.d.ts +0 -1
  37. package/dist/collections/tests/defaultValue.spec.js +0 -95
  38. package/dist/collections/tests/endpoints.spec.d.ts +0 -1
  39. package/dist/collections/tests/endpoints.spec.js +0 -71
  40. package/dist/collections/tests/hooks.spec.d.ts +0 -1
  41. package/dist/collections/tests/hooks.spec.js +0 -156
  42. package/dist/collections/tests/pointField.spec.d.ts +0 -1
  43. package/dist/collections/tests/pointField.spec.js +0 -219
  44. package/dist/collections/tests/relationships.spec.d.ts +0 -1
  45. package/dist/collections/tests/relationships.spec.js +0 -194
  46. package/dist/express/middleware/errorHandler.spec.d.ts +0 -1
  47. package/dist/express/middleware/errorHandler.spec.js +0 -91
  48. package/dist/globals/requestHandlers/globals.spec.d.ts +0 -4
  49. package/dist/globals/requestHandlers/globals.spec.js +0 -174
  50. package/dist/preferences/graphql/resolvers.spec.d.ts +0 -1
  51. package/dist/preferences/graphql/resolvers.spec.js +0 -115
@@ -1 +1 @@
1
- .btn{background:transparent;border:0;border-radius:4px;color:inherit;cursor:pointer;font-size:1rem;font-weight:400;line-height:1.9230769231rem;margin-bottom:1.9230769231rem;margin-top:1.9230769231rem;text-align:center;text-decoration:none}.btn .btn__icon{border:1px solid;border-radius:100%}.btn .btn__icon .stroke{stroke:currentColor;fill:none}.btn .btn__icon .fill{fill:currentColor}.btn--has-tooltip{position:relative}.btn .btn__tooltip{opacity:0;transform:translate(-50%,-10px);visibility:hidden}.btn .btn__content:hover .btn__tooltip{opacity:1;visibility:visible}.btn--icon-style-none .btn__icon,.btn--icon-style-without-border .btn__icon{border:none}.btn span{line-height:1.9230769231rem}.btn span,.btn svg{vertical-align:top}.btn--size-medium{padding:.9615384615rem 1.9230769231rem}.btn--size-small{padding:.4807692308rem .9615384615rem}.btn--style-primary{background-color:var(--theme-elevation-800);color:var(--theme-elevation-0)}.btn--style-primary.btn--disabled{background-color:var(--theme-elevation-400)}.btn--style-primary:not(.btn--disabled):hover{background:var(--theme-elevation-750)}.btn--style-primary:not(.btn--disabled):active{background:var(--theme-elevation-700)}.btn--style-primary:focus{box-shadow:0 0 0 2px var(--theme-success-500);outline:none}.btn--style-secondary{background:none;box-shadow:inset 0 0 0 1px var(--theme-elevation-800);color:var(--theme-elevation-800)}.btn--style-secondary:hover{background:var(--theme-elevation-100);box-shadow:inset 0 0 0 1px var(--theme-elevation-700)}.btn--style-secondary:active{background:var(--theme-elevation-200)}.btn--style-secondary.btn--disabled{background:none;box-shadow:inset 0 0 0 1px var(--theme-elevation-400);color:var(--theme-elevation-400)}.btn--style-secondary:focus{box-shadow:inset 0 0 0 1px var(--theme-elevation-700),0 0 0 2px var(--theme-success-500);outline:none}.btn--style-none{border-radius:0;margin:0;padding:0}.btn--style-none:focus{opacity:.8}.btn--style-none:active{opacity:.7}.btn--round{border-radius:100%}.btn--icon span{display:flex;justify-content:space-between}.btn--icon.btn--style-primary .icon .stroke{stroke:var(--theme-elevation-0);fill:none}.btn--icon.btn--style-primary .icon .fill{fill:var(--theme-elevation-0)}.btn--style-icon-label{font-weight:600;padding:0}.btn--style-light-gray{box-shadow:inset 0 0 0 1px var(--theme-elevation-800)}.btn--icon-position-left .btn__content{flex-direction:row-reverse}.btn--icon-position-left .btn__icon{margin-right:.9615384615rem}.btn--icon-position-right .btn__icon{margin-left:.9615384615rem}.btn--icon-only .btn__icon{margin:0;padding:0}.btn--disabled{cursor:default}.btn:hover .btn__icon{background:var(--theme-elevation-800)}.btn:hover .btn__icon .stroke{stroke:var(--theme-elevation-0);fill:none}.btn:hover .btn__icon .fill{fill:var(--theme-elevation-0)}.btn:focus{outline:none}.btn:focus .btn__icon{background:var(--theme-elevation-150)}.btn:focus .btn__icon .stroke{stroke:var(--theme-elevation-800);fill:none}.btn:focus .btn__icon .fill{fill:var(--theme-elevation-800)}.btn:active .btn__icon{background:var(--theme-elevation-700)}.btn:active .btn__icon .stroke{stroke:var(--theme-elevation-0);fill:none}.btn:active .btn__icon .fill{fill:var(--theme-elevation-0)}.icon--plus{height:1.9230769231rem;width:1.9230769231rem}.icon--plus .stroke,.icon--x line{stroke:var(--theme-elevation-800);stroke-width:1px}.icon--chevron{height:1.9230769231rem;width:1.9230769231rem}.icon--chevron .stroke{fill:none;stroke:var(--theme-elevation-800);stroke-width:2px}.icon--edit{shape-rendering:auto;height:1.9230769231rem;width:1.9230769231rem}.icon--edit .fill{fill:var(--theme-elevation-800);stroke:none}.icon--swap{height:1.9230769231rem;width:1.9230769231rem}.icon--swap .stroke{fill:none;stroke:var(--theme-elevation-800);stroke-width:2px}.tooltip{background-color:var(--theme-elevation-800);border-radius:2px;bottom:100%;color:var(--theme-elevation-0);font-weight:400;line-height:1.4423076923rem;padding:.3846153846rem .7692307692rem;transform:translate3d(-50%,-20%,0);white-space:nowrap;z-index:2}.tooltip,.tooltip span{left:50%;position:absolute}.tooltip span{border:10px solid transparent;border-top:10px solid var(--theme-elevation-800);height:0;top:calc(100% - .12019rem);transform:translateX(-50%);width:0}.popup{position:relative}.popup__content{background:var(--theme-input-bg);display:none;max-width:calc(100vw - 1.92308rem);position:absolute;z-index:var(--z-popup)}.popup__content:after{border:12px solid transparent;border-top:12px solid var(--theme-input-bg);content:" ";position:absolute;top:calc(100% - 1px)}.popup__wrap{overflow:hidden}.popup__scroll{overflow-y:auto;padding:1.9230769231rem;padding-right:calc(var(--scrollbar-width) + 1.92308rem);white-space:nowrap;width:calc(100% + var(--scrollbar-width))}.popup:active,.popup:focus{outline:none}.popup--size-small .popup__scroll{padding:1.4423076923rem calc(var(--scrollbar-width) + 1.44231rem) 1.4423076923rem 1.4423076923rem}.popup--size-small .popup__content{box-shadow:0 0 30px 0 rgba(0,2,4,.12),0 30px 25px -8px rgba(0,2,4,.1)}.popup--size-small.popup--h-align-left .popup__content{left:-.9615384615rem}.popup--size-small.popup--h-align-left .popup__content:after{left:.8173076923rem}.popup--size-large .popup__content{box-shadow:0 20px 35px -10px rgba(0,2,4,.2),0 6px 4px -4px rgba(0,2,4,.02)}.popup--size-large .popup__scroll{padding:2.8846153846rem calc(var(--scrollbar-width) + 2.88462rem) 1.9230769231rem 2.8846153846rem}.popup--size-wide .popup__content{box-shadow:0 0 30px 0 rgba(0,2,4,.12),0 30px 25px -8px rgba(0,2,4,.1)}.popup--size-wide .popup__content:after{border:12px solid transparent;border-top:12px solid var(--theme-input-bg)}.popup--size-wide .popup__scroll{padding:.4807692308rem .9615384615rem}.popup--size-wide.popup--align-left .popup__content{left:-.9615384615rem}.popup--size-wide.popup--align-left .popup__content:after{left:.8173076923rem}.popup--h-align-left .popup__content{left:-3.3653846154rem}.popup--h-align-left .popup__content:after{left:3.3653846154rem}.popup--h-align-center .popup__content,.popup--h-align-center .popup__content:after{left:50%;transform:translateX(-50%)}.popup--h-align-right .popup__content{right:-3.3653846154rem}.popup--h-align-right .popup__content:after{right:3.3653846154rem}.popup--v-align-top .popup__content{bottom:calc(100% + 1.92308rem)}.popup--v-align-bottom .popup__content{box-shadow:0 -2px 20px 7px rgba(0,2,4,.1),0 6px 4px -4px rgba(0,2,4,.02);top:calc(100% + .96154rem)}.popup--v-align-bottom .popup__content:after{border-bottom-color:var(--theme-input-bg);border-top-color:transparent!important;bottom:calc(100% - 1px);top:auto}.popup--v-align-bottom.popup--color-dark .popup__content:after{border-bottom-color:var(--theme-elevation-800)}.popup--color-dark .popup__content{background:var(--theme-elevation-800);color:var(--theme-input-bg)}.popup--color-dark .popup__content:after{border-top-color:var(--theme-elevation-800)}.popup--active .popup__content{display:block}@media(max-width:1024px){.popup--size-large .popup__scroll,.popup__scroll{padding:1.4423076923rem;padding-right:calc(var(--scrollbar-width) + 1.44231rem)}.popup--h-align-left .popup__content{left:-.9615384615rem}.popup--h-align-left .popup__content:after{left:.9615384615rem}.popup--h-align-center .popup__content,.popup--h-align-center .popup__content:after{left:50%;transform:translateX(0)}.popup--h-align-right .popup__content{right:-.9615384615rem}.popup--h-align-right .popup__content:after{right:.9615384615rem}.popup--force-h-align-left .popup__content{left:-.9615384615rem;right:auto;transform:none}.popup--force-h-align-left .popup__content:after{left:.9615384615rem;right:auto;transform:none}.popup--force-h-align-right .popup__content{left:auto;right:-.9615384615rem;transform:none}.popup--force-h-align-right .popup__content:after{left:auto;right:.9615384615rem;transform:none}}.popup-button{display:inline-flex}.banner{background:var(--theme-elevation-900);border:0;border-radius:3px;color:var(--theme-elevation-800);font-size:1rem;line-height:1.9230769231rem;margin-bottom:1.9230769231rem;padding:.9615384615rem;vertical-align:middle}.banner--has-action{cursor:pointer;text-decoration:none}.banner--has-icon{display:flex}.banner--has-icon svg{display:block}.banner--type-default.button--has-action:hover{background:var(--theme-elevation-900)}.banner--type-default.button--has-action:active{background:var(--theme-elevation-950)}.banner--type-error{background:var(--theme-error-100);color:var(--theme-error-500)}.banner--type-error svg .stroke{stroke:var(--theme-error-500);fill:none}.banner--type-error svg .fill{fill:var(--theme-error-500)}.banner--type-error.button--has-action:hover{background:var(--theme-error-200)}.banner--type-error.button--has-action:active{background:var(--theme-error-300)}.banner--type-success{background:var(--theme-success-500)}.banner--type-success.button--has-action:active,.banner--type-success.button--has-action:hover{background:var(--theme-success-200)}.template-minimal{align-items:center;display:flex;justify-content:center;margin-left:auto;margin-right:auto;min-height:100%;padding:5.7692307692rem 1.9230769231rem;width:100%}.template-minimal--width-normal .template-minimal__wrap{max-width:500px;width:100%}.template-minimal--width-wide .template-minimal__wrap{max-width:1024px;width:100%}.icon--check{height:1.9230769231rem;width:1.9230769231rem}.icon--check .stroke{fill:none;stroke:var(--theme-elevation-800);stroke-width:2px}.icon--search{height:1.9230769231rem;width:1.9230769231rem}.icon--search .stroke{stroke:var(--theme-elevation-800);stroke-width:1px}.icon--menu .fill{fill:var(--theme-text)}.pill{background:var(--theme-elevation-150);border:0;border-radius:3px;color:var(--theme-elevation-800);cursor:default;display:inline-flex;font-size:1rem;line-height:1.9230769231rem;overflow:hidden;padding:0 .4807692308rem 0 .6490384615rem;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.pill:active,.pill:focus{outline:none}.pill--has-action{cursor:pointer;text-decoration:none}.pill--has-icon svg{display:block}.pill--align-icon-left{padding-left:.2403846154rem}.pill--align-icon-right{padding-right:.2403846154rem}.pill--style-white{background:var(--theme-elevation-0)}.pill--style-light-gray,.pill--style-light.pill--has-action:active,.pill--style-light.pill--has-action:hover,.pill--style-white.pill--has-action:active,.pill--style-white.pill--has-action:hover{background:var(--theme-elevation-100)}.pill--style-light-gray{color:var(--theme-elevation-800)}.pill--style-warning{background:var(--theme-warning-500)}.pill--style-success{background:var(--theme-success-500);color:var(--color-base-800)}.pill--style-dark{background:var(--theme-elevation-800);color:var(--theme-elevation-0)}.pill--style-dark svg .stroke{stroke:var(--theme-elevation-0);fill:none}.pill--style-dark svg .fill{fill:var(--theme-elevation-0)}.pill--style-dark.pill--has-action:hover{background:var(--theme-elevation-750)}.pill--style-dark.pill--has-action:active{background:var(--theme-elevation-700)}
1
+ .btn{background:transparent;border:0;border-radius:4px;color:inherit;cursor:pointer;font-size:1rem;font-weight:400;line-height:1.9230769231rem;margin-bottom:1.9230769231rem;margin-top:1.9230769231rem;text-align:center;text-decoration:none}.btn .btn__icon{border:1px solid;border-radius:100%}.btn .btn__icon .stroke{stroke:currentColor;fill:none}.btn .btn__icon .fill{fill:currentColor}.btn--has-tooltip{position:relative}.btn .btn__tooltip{opacity:0;transform:translate(-50%,-10px);visibility:hidden}.btn .btn__content:hover .btn__tooltip{opacity:1;visibility:visible}.btn--icon-style-none .btn__icon,.btn--icon-style-without-border .btn__icon{border:none}.btn span{line-height:1.9230769231rem}.btn span,.btn svg{vertical-align:top}.btn--size-medium{padding:.9615384615rem 1.9230769231rem}.btn--size-small{padding:.4807692308rem .9615384615rem}.btn--style-primary{background-color:var(--theme-elevation-800);color:var(--theme-elevation-0)}.btn--style-primary.btn--disabled{background-color:var(--theme-elevation-400)}.btn--style-primary:not(.btn--disabled):hover{background:var(--theme-elevation-750)}.btn--style-primary:not(.btn--disabled):active{background:var(--theme-elevation-700)}.btn--style-primary:focus{box-shadow:0 0 0 2px var(--theme-success-500);outline:none}.btn--style-secondary{background:none;box-shadow:inset 0 0 0 1px var(--theme-elevation-800);color:var(--theme-elevation-800)}.btn--style-secondary:hover{background:var(--theme-elevation-100);box-shadow:inset 0 0 0 1px var(--theme-elevation-700)}.btn--style-secondary:active{background:var(--theme-elevation-200)}.btn--style-secondary.btn--disabled{background:none;box-shadow:inset 0 0 0 1px var(--theme-elevation-400);color:var(--theme-elevation-400)}.btn--style-secondary:focus{box-shadow:inset 0 0 0 1px var(--theme-elevation-700),0 0 0 2px var(--theme-success-500);outline:none}.btn--style-none{border-radius:0;margin:0;padding:0}.btn--style-none:focus{opacity:.8}.btn--style-none:active{opacity:.7}.btn--round{border-radius:100%}.btn--icon span{display:flex;justify-content:space-between}.btn--icon.btn--style-primary .icon .stroke{stroke:var(--theme-elevation-0);fill:none}.btn--icon.btn--style-primary .icon .fill{fill:var(--theme-elevation-0)}.btn--style-icon-label{font-weight:600;padding:0}.btn--style-light-gray{box-shadow:inset 0 0 0 1px var(--theme-elevation-800)}.btn--icon-position-left .btn__content{flex-direction:row-reverse}.btn--icon-position-left .btn__icon{margin-right:.9615384615rem}.btn--icon-position-right .btn__icon{margin-left:.9615384615rem}.btn--icon-only .btn__icon{margin:0;padding:0}.btn--disabled{cursor:default}.btn:hover .btn__icon{background:var(--theme-elevation-800)}.btn:hover .btn__icon .stroke{stroke:var(--theme-elevation-0);fill:none}.btn:hover .btn__icon .fill{fill:var(--theme-elevation-0)}.btn:focus{outline:none}.btn:focus .btn__icon{background:var(--theme-elevation-150)}.btn:focus .btn__icon .stroke{stroke:var(--theme-elevation-800);fill:none}.btn:focus .btn__icon .fill{fill:var(--theme-elevation-800)}.btn:active .btn__icon{background:var(--theme-elevation-700)}.btn:active .btn__icon .stroke{stroke:var(--theme-elevation-0);fill:none}.btn:active .btn__icon .fill{fill:var(--theme-elevation-0)}.icon--plus{height:1.9230769231rem;width:1.9230769231rem}.icon--plus .stroke,.icon--x line{stroke:var(--theme-elevation-800);stroke-width:1px}.icon--chevron{height:1.9230769231rem;width:1.9230769231rem}.icon--chevron .stroke{fill:none;stroke:var(--theme-elevation-800);stroke-width:2px}.icon--edit{shape-rendering:auto;height:1.9230769231rem;width:1.9230769231rem}.icon--edit .fill{fill:var(--theme-elevation-800);stroke:none}.icon--swap{height:1.9230769231rem;width:1.9230769231rem}.icon--swap .stroke{fill:none;stroke:var(--theme-elevation-800);stroke-width:2px}.tooltip{background-color:var(--theme-elevation-800);border-radius:2px;bottom:100%;color:var(--theme-elevation-0);font-weight:400;line-height:1.4423076923rem;padding:.3846153846rem .7692307692rem;transform:translate3d(-50%,-20%,0);white-space:nowrap;z-index:2}.tooltip,.tooltip span{left:50%;position:absolute}.tooltip span{border:10px solid transparent;border-top:10px solid var(--theme-elevation-800);height:0;top:calc(100% - .12019rem);transform:translateX(-50%);width:0}.popup{position:relative}.popup__content{background:var(--theme-input-bg);display:none;max-width:calc(100vw - 1.92308rem);position:absolute;z-index:var(--z-popup)}.popup__content:after{border:12px solid transparent;border-top:12px solid var(--theme-input-bg);content:" ";position:absolute;top:calc(100% - 1px)}.popup__wrap{overflow:hidden}.popup__scroll{overflow-y:auto;padding:1.9230769231rem;padding-right:calc(var(--scrollbar-width) + 1.92308rem);white-space:nowrap;width:calc(100% + var(--scrollbar-width))}.popup:active,.popup:focus{outline:none}.popup--size-small .popup__scroll{padding:1.4423076923rem calc(var(--scrollbar-width) + 1.44231rem) 1.4423076923rem 1.4423076923rem}.popup--size-small .popup__content{box-shadow:0 0 30px 0 rgba(0,2,4,.12),0 30px 25px -8px rgba(0,2,4,.1)}.popup--size-small.popup--h-align-left .popup__content{left:-.9615384615rem}.popup--size-small.popup--h-align-left .popup__content:after{left:.8173076923rem}.popup--size-large .popup__content{box-shadow:0 20px 35px -10px rgba(0,2,4,.2),0 6px 4px -4px rgba(0,2,4,.02)}.popup--size-large .popup__scroll{padding:2.8846153846rem calc(var(--scrollbar-width) + 2.88462rem) 1.9230769231rem 2.8846153846rem}.popup--size-wide .popup__content{box-shadow:0 0 30px 0 rgba(0,2,4,.12),0 30px 25px -8px rgba(0,2,4,.1)}.popup--size-wide .popup__content:after{border:12px solid transparent;border-top:12px solid var(--theme-input-bg)}.popup--size-wide .popup__scroll{padding:.4807692308rem .9615384615rem}.popup--size-wide.popup--align-left .popup__content{left:-.9615384615rem}.popup--size-wide.popup--align-left .popup__content:after{left:.8173076923rem}.popup--h-align-left .popup__content{left:-3.3653846154rem}.popup--h-align-left .popup__content:after{left:3.3653846154rem}.popup--h-align-center .popup__content,.popup--h-align-center .popup__content:after{left:50%;transform:translateX(-50%)}.popup--h-align-right .popup__content{right:-3.3653846154rem}.popup--h-align-right .popup__content:after{right:3.3653846154rem}.popup--v-align-top .popup__content{bottom:calc(100% + 1.92308rem)}.popup--v-align-bottom .popup__content{box-shadow:0 -2px 20px 7px rgba(0,2,4,.1),0 6px 4px -4px rgba(0,2,4,.02);top:calc(100% + .96154rem)}.popup--v-align-bottom .popup__content:after{border-bottom-color:var(--theme-input-bg);border-top-color:transparent!important;bottom:calc(100% - 1px);top:auto}.popup--v-align-bottom.popup--color-dark .popup__content:after{border-bottom-color:var(--theme-elevation-800)}.popup--color-dark .popup__content{background:var(--theme-elevation-800);color:var(--theme-input-bg)}.popup--color-dark .popup__content:after{border-top-color:var(--theme-elevation-800)}.popup--active .popup__content{display:block}@media(max-width:1024px){.popup--size-large .popup__scroll,.popup__scroll{padding:1.4423076923rem;padding-right:calc(var(--scrollbar-width) + 1.44231rem)}.popup--h-align-left .popup__content{left:-.9615384615rem}.popup--h-align-left .popup__content:after{left:.9615384615rem}.popup--h-align-center .popup__content,.popup--h-align-center .popup__content:after{left:50%;transform:translateX(0)}.popup--h-align-right .popup__content{right:-.9615384615rem}.popup--h-align-right .popup__content:after{right:.9615384615rem}.popup--force-h-align-left .popup__content{left:-.9615384615rem;right:auto;transform:none}.popup--force-h-align-left .popup__content:after{left:.9615384615rem;right:auto;transform:none}.popup--force-h-align-right .popup__content{left:auto;right:-.9615384615rem;transform:none}.popup--force-h-align-right .popup__content:after{left:auto;right:.9615384615rem;transform:none}}.popup-button{display:inline-flex}.banner{background:var(--theme-elevation-900);border:0;border-radius:3px;color:var(--theme-elevation-800);font-size:1rem;line-height:1.9230769231rem;margin-bottom:1.9230769231rem;padding:.9615384615rem;vertical-align:middle}.banner--has-action{cursor:pointer;text-decoration:none}.banner--has-icon{display:flex}.banner--has-icon svg{display:block}.banner--type-default.button--has-action:hover{background:var(--theme-elevation-900)}.banner--type-default.button--has-action:active{background:var(--theme-elevation-950)}.banner--type-error{background:var(--theme-error-100);color:var(--theme-error-500)}.banner--type-error svg .stroke{stroke:var(--theme-error-500);fill:none}.banner--type-error svg .fill{fill:var(--theme-error-500)}.banner--type-error.button--has-action:hover{background:var(--theme-error-200)}.banner--type-error.button--has-action:active{background:var(--theme-error-300)}.banner--type-success{background:var(--theme-success-500);color:var(--color-base-800)}.banner--type-success.button--has-action:active,.banner--type-success.button--has-action:hover{background:var(--theme-success-200)}.template-minimal{align-items:center;display:flex;justify-content:center;margin-left:auto;margin-right:auto;min-height:100%;padding:5.7692307692rem 1.9230769231rem;width:100%}.template-minimal--width-normal .template-minimal__wrap{max-width:500px;width:100%}.template-minimal--width-wide .template-minimal__wrap{max-width:1024px;width:100%}.icon--check{height:1.9230769231rem;width:1.9230769231rem}.icon--check .stroke{fill:none;stroke:var(--theme-elevation-800);stroke-width:2px}.icon--search{height:1.9230769231rem;width:1.9230769231rem}.icon--search .stroke{stroke:var(--theme-elevation-800);stroke-width:1px}.icon--menu .fill{fill:var(--theme-text)}.pill{background:var(--theme-elevation-150);border:0;border-radius:3px;color:var(--theme-elevation-800);cursor:default;display:inline-flex;font-size:1rem;line-height:1.9230769231rem;overflow:hidden;padding:0 .4807692308rem 0 .6490384615rem;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.pill:active,.pill:focus{outline:none}.pill--has-action{cursor:pointer;text-decoration:none}.pill--has-icon svg{display:block}.pill--align-icon-left{padding-left:.2403846154rem}.pill--align-icon-right{padding-right:.2403846154rem}.pill--style-white{background:var(--theme-elevation-0)}.pill--style-light-gray,.pill--style-light.pill--has-action:active,.pill--style-light.pill--has-action:hover,.pill--style-white.pill--has-action:active,.pill--style-white.pill--has-action:hover{background:var(--theme-elevation-100)}.pill--style-light-gray{color:var(--theme-elevation-800)}.pill--style-warning{background:var(--theme-warning-500)}.pill--style-success{background:var(--theme-success-500);color:var(--color-base-800)}.pill--style-dark{background:var(--theme-elevation-800);color:var(--theme-elevation-0)}.pill--style-dark svg .stroke{stroke:var(--theme-elevation-0);fill:none}.pill--style-dark svg .fill{fill:var(--theme-elevation-0)}.pill--style-dark.pill--has-action:hover{background:var(--theme-elevation-750)}.pill--style-dark.pill--has-action:active{background:var(--theme-elevation-700)}
@@ -57,6 +57,7 @@
57
57
 
58
58
  &--type-success {
59
59
  background: var(--theme-success-500);
60
+ color: var(--color-base-800);
60
61
 
61
62
  &.button--has-action {
62
63
  &:hover {
@@ -39,7 +39,7 @@ const DefaultNav = () => {
39
39
  var _a, _b;
40
40
  const href = `${admin}/collections/${collection.slug}`;
41
41
  if ((_b = (_a = permissions === null || permissions === void 0 ? void 0 : permissions.collections) === null || _a === void 0 ? void 0 : _a[collection.slug]) === null || _b === void 0 ? void 0 : _b.read.permission) {
42
- return (React.createElement(NavLink, { activeClassName: "active", key: i, to: href },
42
+ return (React.createElement(NavLink, { id: `nav-${collection.slug}`, activeClassName: "active", key: i, to: href },
43
43
  React.createElement(Chevron, null),
44
44
  collection.labels.plural));
45
45
  }
@@ -51,7 +51,7 @@ const DefaultNav = () => {
51
51
  var _a;
52
52
  const href = `${admin}/globals/${global.slug}`;
53
53
  if ((_a = permissions === null || permissions === void 0 ? void 0 : permissions.globals) === null || _a === void 0 ? void 0 : _a[global.slug].read.permission) {
54
- return (React.createElement(NavLink, { activeClassName: "active", key: i, to: href },
54
+ return (React.createElement(NavLink, { id: `nav-global-${global.slug}`, activeClassName: "active", key: i, to: href },
55
55
  React.createElement(Chevron, null),
56
56
  global.label));
57
57
  }
@@ -156,7 +156,7 @@ const ArrayFieldType = (props) => {
156
156
  if (!rows)
157
157
  return null;
158
158
  return (React.createElement(DragDropContext, { onDragEnd: onDragEnd },
159
- React.createElement("div", { id: `field-${path}`, className: classes },
159
+ React.createElement("div", { id: `field-${path.replace(/\./gi, '__')}`, className: classes },
160
160
  React.createElement("div", { className: `${baseClass}__error-wrap` },
161
161
  React.createElement(Error, { showError: showError, message: errorMessage })),
162
162
  React.createElement("header", { className: `${baseClass}__header` },
@@ -159,7 +159,7 @@ const Blocks = (props) => {
159
159
  if (!rows)
160
160
  return null;
161
161
  return (React.createElement(DragDropContext, { onDragEnd: onDragEnd },
162
- React.createElement("div", { id: `field-${path}`, className: classes },
162
+ React.createElement("div", { id: `field-${path.replace(/\./gi, '__')}`, className: classes },
163
163
  React.createElement("div", { className: `${baseClass}__error-wrap` },
164
164
  React.createElement(Error, { showError: showError, message: errorMessage })),
165
165
  React.createElement("header", { className: `${baseClass}__header` },
@@ -32,7 +32,7 @@ const Checkbox = (props) => {
32
32
  } },
33
33
  React.createElement("div", { className: `${baseClass}__error-wrap` },
34
34
  React.createElement(Error, { showError: showError, message: errorMessage })),
35
- React.createElement("input", { id: `field-${path}`, type: "checkbox", name: path, checked: Boolean(value), readOnly: true }),
35
+ React.createElement("input", { id: `field-${path.replace(/\./gi, '__')}`, type: "checkbox", name: path, checked: Boolean(value), readOnly: true }),
36
36
  React.createElement("button", { type: "button", onClick: readOnly ? undefined : () => {
37
37
  setValue(!value);
38
38
  if (typeof onChange === 'function')
@@ -41,7 +41,7 @@ const Code = (props) => {
41
41
  } },
42
42
  React.createElement(Error, { showError: showError, message: errorMessage }),
43
43
  React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
44
- React.createElement(Editor, { id: `field-${path}`, value: value || '', onValueChange: readOnly ? () => null : setValue, highlight: highlighter, padding: 25, style: {
44
+ React.createElement(Editor, { id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onValueChange: readOnly ? () => null : setValue, highlight: highlighter, padding: 25, style: {
45
45
  backgroundColor: 'var(--theme-base-850)',
46
46
  color: 'var(--theme-base-0)',
47
47
  fontFamily: '"Consolas", "Monaco", monospace',
@@ -33,7 +33,7 @@ const DateTime = (props) => {
33
33
  React.createElement("div", { className: `${baseClass}__error-wrap` },
34
34
  React.createElement(Error, { showError: showError, message: errorMessage })),
35
35
  React.createElement(Label, { htmlFor: path, label: label, required: required }),
36
- React.createElement("div", { className: `${baseClass}__input-wrapper`, id: `field-${path}` },
36
+ React.createElement("div", { id: `field-${path.replace(/\./gi, '__')}`, className: `${baseClass}__input-wrapper` },
37
37
  React.createElement(DatePicker, { ...date, placeholder: placeholder, readOnly: readOnly, onChange: readOnly ? undefined : setValue, value: value })),
38
38
  React.createElement(FieldDescription, { value: value, description: description })));
39
39
  };
@@ -31,8 +31,8 @@ const Email = (props) => {
31
31
  width,
32
32
  } },
33
33
  React.createElement(Error, { showError: showError, message: errorMessage }),
34
- React.createElement(Label, { htmlFor: path, label: label, required: required }),
35
- React.createElement("input", { id: `field-${path}`, value: value || '', onChange: setValue, disabled: Boolean(readOnly), placeholder: placeholder, type: "email", name: path, autoComplete: autoComplete }),
34
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
35
+ React.createElement("input", { id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onChange: setValue, disabled: Boolean(readOnly), placeholder: placeholder, type: "email", name: path, autoComplete: autoComplete }),
36
36
  React.createElement(FieldDescription, { value: value, description: description })));
37
37
  };
38
38
  export default withCondition(Email);
@@ -14,7 +14,7 @@ const Group = (props) => {
14
14
  const isWithinGroup = useGroup();
15
15
  const isWithinTab = useTabs();
16
16
  const path = pathFromProps || name;
17
- return (React.createElement("div", { id: `field-${path}`, className: [
17
+ return (React.createElement("div", { id: `field-${path.replace(/\./gi, '__')}`, className: [
18
18
  'field-type',
19
19
  baseClass,
20
20
  isWithinCollapsible && `${baseClass}--within-collapsible`,
@@ -12,6 +12,6 @@ const HiddenInput = (props) => {
12
12
  setValue(valueFromProps, disableModifyingForm);
13
13
  }
14
14
  }, [valueFromProps, setValue, disableModifyingForm]);
15
- return (React.createElement("input", { id: `field-${path}`, type: "hidden", value: value || '', onChange: setValue, name: path }));
15
+ return (React.createElement("input", { id: `field-${path.replace(/\./gi, '__')}`, type: "hidden", value: value || '', onChange: setValue, name: path }));
16
16
  };
17
17
  export default withCondition(HiddenInput);
@@ -39,8 +39,8 @@ const NumberField = (props) => {
39
39
  width,
40
40
  } },
41
41
  React.createElement(Error, { showError: showError, message: errorMessage }),
42
- React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
43
- React.createElement("input", { id: `field-${path}`, value: typeof value === 'number' ? value : '', onChange: handleChange, disabled: readOnly, placeholder: placeholder, type: "number", name: path, step: step }),
42
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
43
+ React.createElement("input", { id: `field-${path.replace(/\./gi, '__')}`, value: typeof value === 'number' ? value : '', onChange: handleChange, disabled: readOnly, placeholder: placeholder, type: "number", name: path, step: step }),
44
44
  React.createElement(FieldDescription, { value: value, description: description })));
45
45
  };
46
46
  export default withCondition(NumberField);
@@ -28,7 +28,7 @@ const Password = (props) => {
28
28
  width,
29
29
  } },
30
30
  React.createElement(Error, { showError: showError, message: errorMessage }),
31
- React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
32
- React.createElement("input", { id: `field-${path}`, value: value || '', onChange: setValue, disabled: formProcessing, type: "password", autoComplete: autoComplete, name: path })));
31
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
32
+ React.createElement("input", { id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onChange: setValue, disabled: formProcessing, type: "password", autoComplete: autoComplete, name: path })));
33
33
  };
34
34
  export default withCondition(Password);
@@ -42,11 +42,11 @@ const PointField = (props) => {
42
42
  React.createElement(Error, { showError: showError, message: errorMessage }),
43
43
  React.createElement("ul", { className: `${baseClass}__wrap` },
44
44
  React.createElement("li", null,
45
- React.createElement(Label, { htmlFor: `field-longitude-${path}`, label: `${label} - Longitude`, required: required }),
46
- React.createElement("input", { id: `field-longitude-${path}`, value: (value && typeof value[0] === 'number') ? value[0] : '', onChange: (e) => handleChange(e, 0), disabled: readOnly, placeholder: placeholder, type: "number", name: `${path}.longitude`, step: step })),
45
+ React.createElement(Label, { htmlFor: `field-longitude-${path.replace(/\./gi, '__')}`, label: `${label} - Longitude`, required: required }),
46
+ React.createElement("input", { id: `field-longitude-${path.replace(/\./gi, '__')}`, value: (value && typeof value[0] === 'number') ? value[0] : '', onChange: (e) => handleChange(e, 0), disabled: readOnly, placeholder: placeholder, type: "number", name: `${path}.longitude`, step: step })),
47
47
  React.createElement("li", null,
48
- React.createElement(Label, { htmlFor: `field-latitude-${path}`, label: `${label} - Latitude`, required: required }),
49
- React.createElement("input", { id: `field-latitude-${path}`, value: (value && typeof value[1] === 'number') ? value[1] : '', onChange: (e) => handleChange(e, 1), disabled: readOnly, placeholder: placeholder, type: "number", name: `${path}.latitude`, step: step }))),
48
+ React.createElement(Label, { htmlFor: `field-latitude-${path.replace(/\./gi, '__')}`, label: `${label} - Latitude`, required: required }),
49
+ React.createElement("input", { id: `field-latitude-${path.replace(/\./gi, '__')}`, value: (value && typeof value[1] === 'number') ? value[1] : '', onChange: (e) => handleChange(e, 1), disabled: readOnly, placeholder: placeholder, type: "number", name: `${path}.latitude`, step: step }))),
50
50
  React.createElement(FieldDescription, { value: value, description: description })));
51
51
  };
52
52
  export default withCondition(PointField);
@@ -24,7 +24,7 @@ const RadioGroupInput = (props) => {
24
24
  React.createElement("div", { className: `${baseClass}__error-wrap` },
25
25
  React.createElement(Error, { showError: showError, message: errorMessage })),
26
26
  React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
27
- React.createElement("ul", { id: `field-${path}`, className: `${baseClass}--group` }, options.map((option) => {
27
+ React.createElement("ul", { id: `field-${path.replace(/\./gi, '__')}`, className: `${baseClass}--group` }, options.map((option) => {
28
28
  let optionValue = '';
29
29
  if (optionIsObject(option)) {
30
30
  optionValue = option.value;
@@ -249,7 +249,7 @@ const Relationship = (props) => {
249
249
  const valueToRender = (findOptionsByValue() || value);
250
250
  if ((valueToRender === null || valueToRender === void 0 ? void 0 : valueToRender.value) === 'null')
251
251
  valueToRender.value = null;
252
- return (React.createElement("div", { id: `field-${path}`, className: classes, style: {
252
+ return (React.createElement("div", { id: `field-${path.replace(/\./gi, '__')}`, className: classes, style: {
253
253
  ...style,
254
254
  width,
255
255
  } },
@@ -110,7 +110,7 @@ const RichText = (props) => {
110
110
  } },
111
111
  React.createElement("div", { className: `${baseClass}__wrap` },
112
112
  React.createElement(Error, { showError: showError, message: errorMessage }),
113
- React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
113
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
114
114
  React.createElement(Slate, { editor: editor, value: valueToRender, onChange: (val) => {
115
115
  if (val !== defaultValue && val !== value) {
116
116
  setValue(val);
@@ -146,7 +146,7 @@ const RichText = (props) => {
146
146
  return null;
147
147
  }))),
148
148
  React.createElement("div", { className: `${baseClass}__editor`, ref: editorRef },
149
- React.createElement(Editable, { id: `field-${path}`, className: `${baseClass}__input`, renderElement: renderElement, renderLeaf: renderLeaf, placeholder: placeholder, spellCheck: true, readOnly: readOnly, onBlur: onBlur, onKeyDown: (event) => {
149
+ React.createElement(Editable, { id: `field-${path.replace(/\./gi, '__')}`, className: `${baseClass}__input`, renderElement: renderElement, renderLeaf: renderLeaf, placeholder: placeholder, spellCheck: true, readOnly: readOnly, onBlur: onBlur, onKeyDown: (event) => {
150
150
  if (event.key === 'Enter') {
151
151
  if (event.shiftKey) {
152
152
  event.preventDefault();
@@ -35,6 +35,7 @@
35
35
  height: auto;
36
36
  position: relative;
37
37
  overflow: hidden;
38
+ flex-shrink: 0;
38
39
 
39
40
  img,
40
41
  svg {
@@ -52,11 +53,13 @@
52
53
  align-items: center;
53
54
  padding: base(.75) base(1);
54
55
  justify-content: space-between;
56
+ max-width: calc(100% - #{base(3.25)});
55
57
  }
56
58
 
57
59
  &__actions {
58
60
  display: flex;
59
61
  align-items: center;
62
+ flex-shrink: 0;
60
63
  }
61
64
 
62
65
  &__actionButton {
@@ -74,7 +77,9 @@
74
77
  }
75
78
 
76
79
  &__collectionLabel {
77
- margin-right: base(3);
80
+ overflow: hidden;
81
+ text-overflow: ellipsis;
82
+ white-space: nowrap;
78
83
  }
79
84
 
80
85
  &__bottomRow {
@@ -99,4 +104,10 @@
99
104
  box-shadow: $focus-box-shadow;
100
105
  outline: none;
101
106
  }
107
+
108
+ @include small-break {
109
+ &__topRowRightPanel {
110
+ padding: base(.75) base(.5);
111
+ }
112
+ }
102
113
  }
@@ -45,6 +45,7 @@
45
45
  h5,
46
46
  h6 {
47
47
  font-family: var(--font-body);
48
+ line-height: 1.125;
48
49
  }
49
50
 
50
51
  h1[data-slate-node=element] {
@@ -124,6 +125,12 @@
124
125
  background-color: var(--theme-elevation-150);
125
126
  }
126
127
  }
128
+
129
+ @include mid-break {
130
+ &__toolbar {
131
+ top: base(3);
132
+ }
133
+ }
127
134
  }
128
135
 
129
136
  [data-slate-node=element] {
@@ -21,12 +21,12 @@ const SelectInput = (props) => {
21
21
  else {
22
22
  valueToRender = options.find((option) => option.value === value);
23
23
  }
24
- return (React.createElement("div", { id: `field-${path}`, className: classes, style: {
24
+ return (React.createElement("div", { id: `field-${path.replace(/\./gi, '__')}`, className: classes, style: {
25
25
  ...style,
26
26
  width,
27
27
  } },
28
28
  React.createElement(Error, { showError: showError, message: errorMessage }),
29
- React.createElement(Label, { htmlFor: path, label: label, required: required }),
29
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
30
30
  React.createElement(ReactSelect, { onChange: onChange, value: valueToRender, showError: showError, isDisabled: readOnly, options: options, isMulti: hasMany, isClearable: isClearable }),
31
31
  React.createElement(FieldDescription, { value: value, description: description })));
32
32
  };
@@ -18,8 +18,8 @@ const TextInput = (props) => {
18
18
  width,
19
19
  } },
20
20
  React.createElement(Error, { showError: showError, message: errorMessage }),
21
- React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
22
- React.createElement("input", { id: `field-${path}`, value: value || '', onChange: onChange, disabled: readOnly, placeholder: placeholder, type: "text", name: path }),
21
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
22
+ React.createElement("input", { id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onChange: onChange, disabled: readOnly, placeholder: placeholder, type: "text", name: path }),
23
23
  React.createElement(FieldDescription, { value: value, description: description })));
24
24
  };
25
25
  export default TextInput;
@@ -17,8 +17,8 @@ const TextareaInput = (props) => {
17
17
  width,
18
18
  } },
19
19
  React.createElement(Error, { showError: showError, message: errorMessage }),
20
- React.createElement(Label, { htmlFor: `field-${path}`, label: label, required: required }),
21
- React.createElement("textarea", { id: `field-${path}`, value: value || '', onChange: onChange, disabled: readOnly, placeholder: placeholder, name: path, rows: rows }),
20
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
21
+ React.createElement("textarea", { id: `field-${path.replace(/\./gi, '__')}`, value: value || '', onChange: onChange, disabled: readOnly, placeholder: placeholder, name: path, rows: rows }),
22
22
  React.createElement(FieldDescription, { value: value, description: description })));
23
23
  };
24
24
  export default TextareaInput;
@@ -52,7 +52,7 @@ const UploadInput = (props) => {
52
52
  width,
53
53
  } },
54
54
  React.createElement(Error, { showError: showError, message: errorMessage }),
55
- React.createElement(Label, { htmlFor: path, label: label, required: required }),
55
+ React.createElement(Label, { htmlFor: `field-${path.replace(/\./gi, '__')}`, label: label, required: required }),
56
56
  (collection === null || collection === void 0 ? void 0 : collection.upload) && (React.createElement(React.Fragment, null,
57
57
  (file && !missingFile) && (React.createElement(FileDetails, { collection: collection, doc: file, handleRemove: () => {
58
58
  onChange(null);
@@ -55,7 +55,7 @@ const DefaultGlobalView = (props) => {
55
55
  ((_l = global.versions) === null || _l === void 0 ? void 0 : _l.drafts) && (React.createElement(React.Fragment, null,
56
56
  !global.versions.drafts.autosave && (React.createElement(SaveDraft, null)),
57
57
  React.createElement(Publish, null))),
58
- !((_m = global.versions) === null || _m === void 0 ? void 0 : _m.drafts) && (React.createElement(FormSubmit, null, "Save"))))),
58
+ !((_m = global.versions) === null || _m === void 0 ? void 0 : _m.drafts) && (React.createElement(FormSubmit, { buttonId: "action-save" }, "Save"))))),
59
59
  React.createElement("div", { className: `${baseClass}__sidebar-fields` },
60
60
  (preview && (((_o = global.versions) === null || _o === void 0 ? void 0 : _o.drafts) && !((_q = (_p = global.versions) === null || _p === void 0 ? void 0 : _p.drafts) === null || _q === void 0 ? void 0 : _q.autosave))) && (React.createElement(PreviewButton, { generatePreviewURL: preview, data: data })),
61
61
  ((_r = global.versions) === null || _r === void 0 ? void 0 : _r.drafts) && (React.createElement(React.Fragment, null,
@@ -28,7 +28,7 @@
28
28
  letter-spacing: -1px;
29
29
 
30
30
  @include small-break {
31
- letter-spacing: base(0);
31
+ letter-spacing: -.5px;
32
32
  font-size: base(1.25);
33
33
  line-height: base(1.25);
34
34
  }
@@ -66,6 +66,10 @@ For example, you may wish to have two Collections that both support `Authenticat
66
66
 
67
67
  This is totally possible. For the above scenario, by specifying `admin: { user: 'admins' }`, your Payload Admin panel will use `admins`. Any users logged in as `customers` will not be able to log in via the Admin panel.
68
68
 
69
+ ### Light and dark modes
70
+
71
+ Users in the admin panel have access to choosing between light mode and dark mode for their editing experience. The setting is managed while logged into the admin UI within the user account page and will be stored with the browser. By default, the operating system preference is detected and used.
72
+
69
73
  ### Restricting user access
70
74
 
71
75
  If you would like to restrict which users from a single Collection can access the Admin panel, you can use the `admin` access control function. [Click here](/docs/access-control/overview#admin) to learn more.
@@ -12,16 +12,18 @@ To enable Authentication on a collection, define an `auth` property and set it t
12
12
 
13
13
  ## Options
14
14
 
15
- | Option | Description |
16
- | ---------------------- | -------------|
17
- | **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More](/docs/authentication/config#api-keys) |
18
- | **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
19
- | **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
20
- | **`lockTime`** | Set the time that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
21
- | **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the express `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
22
- | **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
23
- | **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) |
24
- | **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) |
15
+ | Option | Description |
16
+ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17
+ | **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More](/docs/authentication/config#api-keys) |
18
+ | **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
19
+ | **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
20
+ | **`lockTime`** | Set the time that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
21
+ | **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the express `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
22
+ | **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
23
+ | **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) |
24
+ | **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) |
25
+ | **`disableLocalStrategy`** | Advanced - disable Payload's built-in local auth strategy. Only use this property if you have replaced Payload's auth mechanisms with your own. |
26
+ | **`strategies`** | Advanced - an array of PassportJS authentication strategies to extend this collection's authentication with. [More](/docs/authentication/config#strategies) |
25
27
 
26
28
  ### API keys
27
29
 
@@ -37,7 +39,8 @@ Technically, both of these options will work for third-party integrations but th
37
39
  To enable API keys on a collection, set the `useAPIKey` auth option to `true`. From there, a new interface will appear in the Admin panel for each document within the collection that allows you to generate an API key for each user in the Collection.
38
40
 
39
41
  <Banner type="success">
40
- User API keys are encrypted within the database, meaning that if your database is compromised, your API keys will not be.
42
+ User API keys are encrypted within the database, meaning that if your database
43
+ is compromised, your API keys will not be.
41
44
  </Banner>
42
45
 
43
46
  ##### Authenticating via API Key
@@ -45,8 +48,9 @@ To enable API keys on a collection, set the `useAPIKey` auth option to `true`. F
45
48
  To utilize your API key while interacting with the REST or GraphQL API, add the `Authorization` header.
46
49
 
47
50
  **For example, using Fetch:**
51
+
48
52
  ```js
49
- const response = await fetch('http://localhost:3000/api/pages', {
53
+ const response = await fetch("http://localhost:3000/api/pages", {
50
54
  headers: {
51
55
  Authorization: `${collection.labels.singular} API-Key ${YOUR_API_KEY}`,
52
56
  },
@@ -62,8 +66,13 @@ You can customize how the Forgot Password workflow operates with the following o
62
66
  Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users attempting to reset their password. The function should return a string that supports HTML, which can be a full HTML email.
63
67
 
64
68
  <Banner type="success">
65
- <strong>Tip:</strong><br />
66
- HTML templating can be used to create custom email templates, inline CSS automatically, and more. You can make a reusable function that standardizes all email sent from Payload, which makes sending custom emails more DRY. Payload doesn't ship with an HTML templating engine, so you are free to choose your own.
69
+ <strong>Tip:</strong>
70
+ <br />
71
+ HTML templating can be used to create custom email templates, inline CSS
72
+ automatically, and more. You can make a reusable function that standardizes
73
+ all email sent from Payload, which makes sending custom emails more DRY.
74
+ Payload doesn't ship with an HTML templating engine, so you are free to choose
75
+ your own.
67
76
  </Banner>
68
77
 
69
78
  Example:
@@ -99,8 +108,13 @@ Example:
99
108
  ```
100
109
 
101
110
  <Banner type="warning">
102
- <strong>Important:</strong><br />
103
- If you specify a different URL to send your users to for resetting their password, such as a page on the frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL reset-password operation yourself on your frontend, using the token that was provided for you. Above, it was passed via query parameter.
111
+ <strong>Important:</strong>
112
+ <br />
113
+ If you specify a different URL to send your users to for resetting their
114
+ password, such as a page on the frontend of your app or similar, you need to
115
+ handle making the call to the Payload REST or GraphQL reset-password operation
116
+ yourself on your frontend, using the token that was provided for you. Above,
117
+ it was passed via query parameter.
104
118
  </Banner>
105
119
 
106
120
  **`generateEmailSubject`**
@@ -153,8 +167,13 @@ Example:
153
167
  ```
154
168
 
155
169
  <Banner type="warning">
156
- <strong>Important:</strong><br />
157
- If you specify a different URL to send your users to for email verification, such as a page on the frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL verification operation yourself on your frontend, using the token that was provided for you. Above, it was passed via query parameter.
170
+ <strong>Important:</strong>
171
+ <br />
172
+ If you specify a different URL to send your users to for email verification,
173
+ such as a page on the frontend of your app or similar, you need to handle
174
+ making the call to the Payload REST or GraphQL verification operation yourself
175
+ on your frontend, using the token that was provided for you. Above, it was
176
+ passed via query parameter.
158
177
  </Banner>
159
178
 
160
179
  **`generateEmailSubject`**
@@ -177,3 +196,15 @@ Example:
177
196
  }
178
197
  }
179
198
  ```
199
+
200
+ ### Strategies
201
+
202
+ As of Payload `1.0.0`, you can add additional authentication strategies to Payload easily by passing them to your collection's `auth.strategies` array.
203
+
204
+ Behind the scenes, Payload uses PassportJS to power its local authentication strategy, so most strategies listed on the PassportJS website will work seamlessly. Combined with adding custom components to the admin panel's `Login` view, you can create advanced authentication strategies directly within Payload.
205
+
206
+ <Banner type="warning">
207
+ This is an advanced feature, so only attempt this if you are an experienced
208
+ developer. Otherwise, just let Payload's built-in authentication handle user
209
+ auth for you.
210
+ </Banner>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload",
3
- "version": "0.20.10-beta.0",
3
+ "version": "1.0.4",
4
4
  "description": "Node, React and MongoDB Headless CMS and Application Framework",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -32,20 +32,15 @@
32
32
  "build:components": "webpack --config dist/webpack/components.config.js",
33
33
  "build": "yarn copyfiles && yarn build:tsc && yarn build:components",
34
34
  "build:watch": "nodemon --watch 'src/**' --ext 'ts,tsx' --exec 'yarn build:tsc'",
35
- "demo:build:analyze": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts PAYLOAD_ANALYZE_BUNDLE=true node dist/bin/build",
36
- "demo:build": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts node dist/bin/build",
37
- "demo:generate:types": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts node dist/bin/generateTypes",
38
- "demo:generate:graphqlschema": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts node dist/bin/generateGraphQLSchema",
39
- "demo:serve": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts NODE_ENV=production nodemon",
40
35
  "dev": "nodemon",
41
- "dev:generatetypes": "node ./test/generateTypes.js",
36
+ "dev:generate-types": "node ./test/generateTypes.js",
42
37
  "pretest": "yarn build",
43
38
  "test": "yarn test:int && yarn test:components",
44
- "test:int": "cross-env NODE_ENV=test DISABLE_LOGGING=true jest --forceExit --detectOpenHandles",
45
- "test:e2e": "cross-env NODE_ENV=test DISABLE_LOGGING=true playwright test",
46
- "test:e2e:headed": "cross-env NODE_ENV=test DISABLE_LOGGING=true playwright test --headed",
47
- "test:e2e:debug": "cross-env PWDEBUG=1 NODE_ENV=test DISABLE_LOGGING=true playwright test",
48
- "test:components": "cross-env PAYLOAD_CONFIG_PATH=demo/payload.config.ts NODE_ENV=test jest --config=jest.components.config.js",
39
+ "test:int": "cross-env DISABLE_LOGGING=true jest --forceExit --detectOpenHandles",
40
+ "test:e2e": "cross-env DISABLE_LOGGING=true playwright test",
41
+ "test:e2e:headed": "cross-env DISABLE_LOGGING=true playwright test --headed",
42
+ "test:e2e:debug": "cross-env PWDEBUG=1 DISABLE_LOGGING=true playwright test",
43
+ "test:components": "cross-env jest --config=jest.components.config.js",
49
44
  "clean": "rimraf dist",
50
45
  "release": "release-it",
51
46
  "release:patch": "release-it patch",