richardtallent / vue-simple-calendar

Simple Vue component to show a month-grid calendar with events
MIT License
878 stars 159 forks source link

Default to no style #45

Closed rickmills closed 6 years ago

rickmills commented 6 years ago

This might sound slightly strange but hear me out. One of vue's weaknesses seems to be the inability to either disable or completely override the style portion of an included vue component such as simple calendar.

The 'base style' serves as a great starting point, and obviously will be very helpful in most situations.

However in those situations where you want to have your own style, the only way to do this is to add your own style, and use a ton of important tags.

My suggestion would be a very minor change to essentially split the 'default' theme to be loaded up by a class instead of applying it out of the box.

E.g instead of this showing the default style:

<calendar-view :show-date="showDate" @setShowDate="setShowDate" />

Have it so that to show the default style you do something like this:

<calendar-view :show-date="showDate" @setShowDate="setShowDate" class="sc-default" />

Pros

Cons

Happy to send over a pull request should there be any interest in this.

richardtallent commented 6 years ago

Hi Rick,

This is something I've had to deal with on a number of components, so I'm with you. For this component, the original strategy was:

  1. Don't use scoped, because it's too difficult to override.
  2. The SFC only contains styles required for core functionality.
  3. Everything else goes in the "default" external stylesheet, which devs can use, ignore, or build on.

Rule 2 was based on the logic that the calendar should still function (show a calendar with the content overlapping in the appropriate places, buttons with labels, etc.) even if no theme is specified. I.e., it shouldn't break out of the box just because someone forgot to include a CSS file. Most of these properties are interrelated in ways that really shouldn't be overridden. A few, such as border-color and background-color, are theoretically optional, but from a practical standpoint, still require a default.

However, I did bend Rule 2 in a few places, and I'm planning to get these styles our of the SFC and back into the external default theme so the baseline is as clean as possible:

Another big change I'd like to make: my original choices for core class names (event, day, etc.) are generic terms, so they need deep selectors to ensure the component doesn't blow up something else on the page. But this also makes them a pain to override or theme. Using "day" for both the header and the dates was a bad idea too. So I'm thinking about using slightly more terse names (such as "cv-event") so the selectors can be shallow and thus easier to reason about. That would be a breaking change, so I want to be sure it's the right call before breaking anyone's existing customizations.

And... now I'm re-reading your question and thinking you may be talking about something entirely different. :)

If you're referring to requiring someone to add a class to enable the default.css theme, I'm not sure why that would help... the default.css file is purely optional, it's just an example theme, so anyone can just skip it if they'd rather build their own theme from scratch.

What they can't skip is the "baseline" theme--the part inside the SFC. But as mentioned above, those CSS rules are primarily implementing core functionality, so they shouldn't be overridden, and they steer clear of most someone might want to customize (fonts, fancy borders, drop-shadows, colors, and the like).

Muffinman commented 6 years ago

FWIW borders and background colours are two things which I wouldn't consider 'core' required functionality and yet are not straight forward to override!

In my opinion the core CSS block should only contain layout, all other styling (fonts, colours, borders, sizes, text-alignment etc.) should be linked from an external file.

Also the few css content: declarations are a bit iffy, perhaps there could be an additional prop to define these and render them with Vue?

richardtallent commented 6 years ago

My working definition of "core" styling is that with no external CSS, the calendar should look like a calendar, events should look like events, and the resulting render should be clean and tasteful, if bare.

In 2.2.0 (not yet up, webpack 4 issue, but should be soon), the only remaining background color in the core CSS is for the events. There, it is necessary because transparent events are just plain ugly. Border definitions are necessary in the baseline CSS because the positioning of the events with their offset, span, and slot need to include assumptions about border metrics. Also, because divs lack a "border-collapse" feature, some elements require half-borders to avoid double-borders, and that's the sort of implementation detail that should be have a reasonable default so theme developers don't have to start with broken borders. A color is defined for those borders because the default color (black) is also unreasonably visually offensive. In previous versions, a background color for each day was required, but I was able to get rid of that requirement recently.

For the next version, 3.0, I'm focusing on two big changes:

  1. More granular and flexible header slots. As part of this, I'll remove the CSS-based header button content, since developers will have better options for overriding the buttons completely (for instance, being able to use the Bootstrap, Bulma, Vuetify, or other buttons they use elsewhere, along with whatever label they want). I'm still working out the "right" way for a child slot component to change the displayed period--one in keeping with Vue's "props in, events out" philosophy.

  2. Greatly simplifying the CSS, replacing the deep cascading rules with unique but flatter, simpler class names. This should make overriding anything from either the baseline or the default theme trivial. I'll be looking for some feedback on these class names from users like you who are actually customizing the look and feel. (Modifier classes like "past" will probably remain the same.)

It shouldn't take too long for this version to follow, the 3.x number is less about the effort involved and more just to avoid problems for people who might routinely upgrade for point releases and who depend on a lot of CSS customization. I'll probably be working on it while I'm at VueConf in a few weeks.

richardtallent commented 6 years ago

Just an update, 2.2.0 is out, which includes some refactoring of nonessential (as defined above) CSS decoration out of the core SFC style block and into the (optional) default.css theme.

Leaving this open and moving it to the 3.0 milestone, since that's where I'll be making changes to the class structure to (hopefully) make overriding of the themes far easier (i.e., shouldn't need !important directives or complex cascaded selectors just to change some colors, etc.).

richardtallent commented 6 years ago

In 3.0 (about to publish), resolved many of the concerns here (default theme requires a class name to activate, baseline theme uses a flatter class name structure that is easier to override, easy header slot with properties, etc.).